假设我有以下课程:
class A{
...
B obj;
C obj2
...
}在构造A实例时,B obj将由默认构造函数初始化。但是在构造obj和obj2之前,我需要在A的构造函数中做一些计算,然后为B obj和C obj2调用一个非默认的构造函数。
这不需要花很多钱,但是在构造A时调用B obj和C obj2的默认构造函数是完全不必要的。
我能阻止C++调用默认构造函数吗?还是说这是错误的做法?
编辑:为了澄清,我添加了第二个对象。我必须从文件中读取,然后才能构造B和C。
发布于 2014-07-02 12:01:41
这是有点错误的做法。我建议你这样做:
int arguments(){ //assuming obj takes an int as 3rd constructor argument, could be any
//do computation you wanted to do in A::A
}
class A{
A() : obj(non, Default, arguments()){}
B obj;
}现在初始化是在创建obj之前完成的。您还可以使arguments返回一个B并依赖于B的移动构造函数。
编辑:答案与编辑后的问题变化不大。现在有两个对象,但同样的逻辑适用于:
class A{
A() : obj(doInitCalculations()), obj2(something){}
B obj;
C obj2;
}obj必须在obj2之前初始化(即使您编写了A() : obj2(), obj1{}),因为它们是按照类中声明的顺序构造的。因此,在构造任何一个对象之前,仍然会调用doInitCalculations。
发布于 2014-07-02 12:02:07
您可以委托构造函数,类似于:
class A
{
public:
A() : A(ComputeSomethingForBAndC()) {}
private:
A(const DataToBuildBAndC& dataToBuildBAndC) :
b(dataToBuildBAndC),
c(dataToBuildBAndC)
{}
private:
B b;
C c;
};发布于 2014-07-02 12:10:59
无论您做什么,在您进入B的主体之前,都将调用A的构造函数。如果没有在初始化程序列表中指定任何内容,则将调用默认构造函数。如果您需要先计算值,那么唯一的实际解决方案是在静态成员函数中这样做:
class A
{
B obj;
static B initializeB( ... );
public:
A( ... ) : obj( initializeB( ... ) ) {}
};如果计算只依赖于参数,并且仅用于B的初始化,则这很好。否则,可能需要执行两次相同的计算。
如果B的初始化依赖于其他成员(这些成员也是计算出来的),那么您可以将其他成员放在obj之前(因此将首先初始化它们),并对它们使用静态成员技巧。(只需确保给出一个重要的注释,即您的代码完全取决于成员的顺序。)
最后,如果没有其他的工作,您可以为B安排一个“琐碎”的构造函数,该构造函数只执行最小值,以便以后的赋值能够工作。然后你可以写:
A::A()
: obj( doNothing )
{
// all the calculation
obj = B(...);
}(对于doNothing,只需使用枚举:
enum DoNothing { doNothing };)在B::B( DoNothing )中提供重载的B。)
我认为这是最后的手段,因为它涉及修改B,这是相当有侵略性的。不过,我以前也用过一两次。
https://stackoverflow.com/questions/24530404
复制相似问题