没有默认构造函数的成员对象的初始化列表

时间:2014-03-25 18:39:42

标签: c++ class initialization

我读到了在类中初始化的引用和对象。但是,除了提示之外,我找不到明确的陈述:

如果初始化列表中没有默认构造函数(没有obj1),我可以初始化成员对象Object(){}吗?

class Sample
{
private:
      Object1 obj1(arguments);
public:
     Sample(Object1 o1)  : obj1( o1(arguments) )
     { }
};

问题出现了,因为如果遇到与此How can I initialize C++ object member variables in the constructor?相关的问题。代码也从那里获取。谢谢你的努力。

丹尼尔

修改

由于答案表明它有效,测试返回错误(这正是我提出这个问题的原因):

../src/Timestep.h:45:12: error: field ‘myFEMSolver’ has incomplete type FEMSolver myFEMSolver;

代码:

class Timestep {
public:
  Timestep();
private:
  FEMSolver myFEMSolver;
}

Timestep::Timestep() : myFEMSolver(*this)
  { //do some stuff
}

FEMSolver::FEMSolver(const Timestep& theTimestep) : myTimestep(theTimestep)
  { //do some stuff
}

main(){
  Timestep myTimestep();
}

3 个答案:

答案 0 :(得分:6)

  

如果初始化列表中没有默认构造函数(没有obj1),我可以初始化成员对象Object(){}吗?

是。事实上,你必须这样做。

class Sample
{
    private:

        Object1 obj1;

    public:

        Sample() : obj1( /* ctor args */ )
        {
        }
};

如果您将另一个Object1传递给Sample构造函数,并将其传递给Object1的复制构造函数,那么您可能希望通过引用传递它:

Sample(const Object1& o) : obj1(o)
{
}

如果Object1没有无参数构造函数,并且您没有初始化初始化列表中的obj1,则会出现编译错误。

答案 1 :(得分:0)

按如下方式更改您的班级声明:

class Sample
{
private:
      Object1 obj1;
public:
     Sample(const Object1& o1)  : obj1(o1)
     { }
};

要调用Sample构造函数,请使用:

Sample s(Object1(arguments));

这要求您的Object1是一个所谓的 nice 类(提供复制构造函数和赋值运算符)。
对于任何其他情况,您需要使用Object1的引用或指针作为Sample类中的成员。

另一种(更简单的)方法是通过以下方式传递参数:

class Sample
{
private:
      Object1 obj1;
public:
     Sample(Args& arguments)  : obj1(arguments)
     { }
};

答案 2 :(得分:0)

您似乎要在列表初始化程序中提供现有Object1,或在嵌套列表初始值设定项中创建Object1,除非Object1的构造函数是明确的。所以,让我们说我们有

struct Object1
{
    Object1(int, int) { };
};

然后,通过复制,移动或自己的参数在Object1内初始化Sample的最通用的方法是:

class Sample
{
private:
    Object1 obj1;
public:
    Sample(Object1&& o1) : obj1(std::move(o1)) { }
    Sample(const Object1& o1) : obj1(o1) { }

    template<
        typename... A,
        typename = typename std::enable_if<std::is_constructible<Object1, A...>{}>
    >
    Sample(A&&... a) : obj1(std::forward<A>(a)...) { }
};

这允许我们使用各种Sample构造:

int main ()
{
    Object1 o1{1, 2};
    const Object1& o2{o1};
    Sample s1{Object1{1, 2}};
    Sample s2{{1, 2}};
    Sample s3{1, 2};
    Sample s4{o1};
    Sample s5{o2};
}

如果Object1的构造函数为explicit,则不允许s2。根据您想要支持的内容,您当然可以通过多种方式简化Sample