在构造函数中为另一个相同类型的对象构造对象是个好主意吗



让我们以这个简化的代码示例为例:

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);
  }
};

相关内容

最新更新