【问题标题】:calling constructor of a class member in constructor在构造函数中调用类成员的构造函数
【发布时间】:2011-12-07 09:09:15
【问题描述】:

我可以在类的构造函数中调用成员的构造函数吗?

假设我的班级 MClass 中有班级类型为 foo 的成员 bar。我可以在 MClass 的构造函数中调用 bar 的构造函数吗?如果没有,我该如何初始化我的会员栏?

这是在组合(聚合)中初始化成员的问题。

【问题讨论】:

    标签: c++ constructor aggregation


    【解决方案1】:

    是的,当然可以!这就是 构造函数初始化列表 的用途。这是初始化没有默认构造函数以及常量和引用的成员所需的基本功能:

    class Foo
    {
      Bar x;     // requires Bar::Bar(char) constructor
      const int n;
      double & q;
    public:
      Foo(double & a, char b) : x(b), n(42), q(a) { }
      //                      ^^^^^^^^^^^^^^^^^^^
    };
    

    您还需要初始化列表来为派生类构造函数中的基类指定非默认构造函数。

    【讨论】:

    • 为什么语言规范需要像这样用括号调用的构造函数的初始化列表,但是您可以在类声明中调用像 std::atomic_bool myBool{false} 这样的卷曲初始化构造函数?我想要做的就是设置我的原子布尔的初始化值,而不向我的类def添加构造函数代码,出于某种原因,我必须把它当作一个数组初始化,现在我的头在旋转(╯°□°)╯︵┻━┻
    【解决方案2】:

    是的,您可以:

    #include <iostream>
    
    using std::cout;
    using std::endl;
    
    class A{
    public:
        A(){
            cout << "parameterless" << endl;
        }
    
        A(const char *str){
            cout << "Parameter is " << str <<endl;
        }
    };
    
    class B{
        A _argless;
        A _withArg;
    
    public:
        // note that you need not call argument-less constructor explicitly.
        B(): _withArg("42"){
        }
    };
    
    int main(){
        B b;
    
        return 0;
    }
    

    输出是:

    parameterless
    Parameter is 42
    

    View this on ideone.com

    【讨论】:

    • 您对无需显式调用的无参数成员构造函数的评论正是我想要的。谢谢!
    【解决方案3】:

    像这样:

    class C {
      int m;
    
    public:
    
      C(int i):
        m(i + 1) {}
    
    };
    

    如果你的成员构造函数需要参数,你可以传递它们。它们可以是由类构造函数参数和已经初始化的类型组成的表达式。

    记住:成员按照它们在类中声明的顺序进行初始化,而不是它们在初始化列表中出现的顺序。

    【讨论】:

      【解决方案4】:

      通过初始化列表,如果基类没有默认构造函数。

      struct foo{
         foo( int num )
         {}
      };
      
      struct bar : foo {
         bar( int x ) : foo(x)
                     // ^^^^^^ initializer list
         {}
      };
      

      【讨论】:

        【解决方案5】:

        是的,你可以。这是在类的初始化列表中完成的。例如:

        class MClass 
        {
        
          foo bar;
        
        public:
        
          MClass(): bar(bar_constructor_arguments) {};
        }
        

        这将使用传入的参数构造bar。通常,参数将是您的类的其他成员或传递给您的构造函数的参数。任何没有无参数构造函数的成员都需要此语法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-06
          • 1970-01-01
          • 2012-01-10
          • 1970-01-01
          • 2012-09-28
          • 1970-01-01
          相关资源
          最近更新 更多