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

C++ 在构造函数中为同一类型的另一个构造函数构造对象是一个好主意吗?,c++,C++,让我们以这个简化的代码示例为例: class X { int val; public: X(int abc):val(abc){} X() { X *b = new X(123); val = b->val; delete b; } }; 这个设计好吗?这是反模式吗?若然,原因为何 注意:这是一个人为的例子。在更现实的场景中,构造函数被传递到树的根,并基于左、右子级构建其状态,这是通过将子级传递给其他构造函数来构建对象而获得的 不,这不是一个

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

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

不,这不是一个好的设计,因为你有它上面介绍。当您在构造函数的主体中时,
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);
  }
};

在第一个构造函数中完成的所有计算都应该在一个函数中。在第二个构造函数中,不是创建一个新对象来调用第一个构造函数,而是调用这个新函数来计算所需内容并传递123

注意:我已经很久没有用C编写代码了

class X 
{
 int val;
 public:
  X(int abc):val(abc){ val = DoCalculation(123); }
  X()
  {
    val = DoCalculation(123);
  }
};

正如所写的,你有一个内存泄漏,除非这是一个人为的例子,否则你已经做了大量额外的工作来表示
val=123
。你可以用一个构造函数来实现这一点:
X(int abc=123):val(abc){}
(减去内存泄漏)为什么不直接做
xb(123);val=b.val?上述示例并不表示需要完成的工作。这只是为了得到设计上的一个输入。正如所写的那样,你有一个内存泄漏,除非这是一个人为的例子,否则你已经做了大量额外的工作来表示
val=123
。你只需要一个构造函数就可以做到这一点:
X(intabc=123):val(abc){}
(减去内存泄漏)你为什么不直接做
xb(123);val=b.val?上述示例并不表示需要完成的工作。这只是为了得到设计上的输入。不,这个例子太简单了。假设对象X是对象A、B和C的函数。。不仅仅是简单的参数分配。你能添加另一个代码示例来更好地捕捉你想要的吗?@SridharIyer:不过,你还是想要一个转发构造函数,所以你只需要一个使用对象a、B和C的地方。不,这个示例过于简单了。假设对象X是对象A、B和C的函数。。不仅仅是简单的参数分配。你能添加另一个代码示例来更好地捕获你想要的吗?@SridharIyer:不过,你还是想要一个转发构造函数,所以你只需要一个使用对象a、B和C的地方。