让我们以这个简化的代码示例为例:
class X
{
int val;
public:
X(int abc):val(abc){}
X()
{
X *b = new X(123);
val = b->val;
delete b;
}
};
这个设计好吗?这是反模式吗?如果是,为什么?
注:这是一个人为的例子。在一个更现实的场景中,构造函数被传递到树的根,它基于左和右子级构建其状态,该状态是通过将子级传递给其他构造函数来构建对象而获得的。
不,这不是一个好的设计,就像上面介绍的那样。当您在构造函数的主体中时,class X
的对象实例此时已经完全构造完成。如果X
的成员具有非常昂贵的构造,那么您只需要先构造它们,然后再将新值重新分配给它们,就可以完成额外的工作。您的示例还在X
的对象构造过程中强制进行堆分配,这在这里是完全不必要的。
C++11提供了一种称为转发构造函数的东西来实现这一点:
class X
{
int val;
public:
X(int abc) : val(abc) {}
X() : X(123) {}
};
对于C++03,您可以重构上面的内容,只使用第一个参数的默认值:
class X
{
int val;
public:
X(int abc = 123) : val(abc) {}
};
在第一个构造函数中完成的所有计算都应该在一个函数中。在第二个构造函数中,您不需要创建一个新对象来调用第一个构造函数,而只需要调用这个新函数来计算您想要的内容并传递123。
注意:我已经很久没有用C编码了
class X
{
int val;
public:
X(int abc):val(abc){ val = DoCalculation(123); }
X()
{
val = DoCalculation(123);
}
};