C++ 使用init方法避免使用new分配对象-这是一个糟糕的设计吗?

C++ 使用init方法避免使用new分配对象-这是一个糟糕的设计吗?,c++,class,constructor,initialization,new-operator,C++,Class,Constructor,Initialization,New Operator,在C++中设计类时,我最近开始使用init方法,而不是将参数传递给构造函数: Class A { public: A(); init(int number); ... }; 而不是: Class A { public: A(int number); }; 这允许我在其他类中使用作为成员,如: class B { A m_a; }; 与我过去的做法不同: class B { A *m_a; }; 然后在B的构造函数中分配m_a 使用init函数的好处是,我不必担心删除m_a,因为当B的实例

在C++中设计类时,我最近开始使用init方法,而不是将参数传递给构造函数:

Class A {
public:
A();
init(int number);
...
};
而不是:

Class A {
public:
A(int number);
};
这允许我在其他类中使用作为成员,如:

class B {
A m_a;
};
与我过去的做法不同:

class B {
A *m_a;
};
然后在B的构造函数中分配m_a

使用init函数的好处是,我不必担心删除m_a,因为当B的实例被销毁时,m_a将被销毁

我的问题是:使用init方法有什么我应该知道的缺点吗?这会使堆栈溢出吗


到目前为止,一切都运行良好,但我认为在以这种方式编写大量代码之前,我应该询问一下

不必使用指针将类实例作为属性

Class B {
public:
    explicit B(int i); // notice the explicit, btw
    A m_a;
};

B::B(int i)
    : m_a(i) { // will call the constructor of "A" with "i" as argument
}
当B的实例也被销毁时,m_a将被销毁


通过添加一个init方法,您就违背了构造函数的目的:您可以拥有一个未完全构建的对象。与其忘记删除m_a,不如冒险忘记初始化它。

您可以按值存储属性,即使您需要非默认构造函数来实例化它们。在类B的构造函数中,您需要通过初始化列表显式地实例化m_a,例如Bint number:m_anumber{}。在这里,使用初始化函数来解决这个问题确实是不必要的,因为语言本身就支持这个问题。

这是一个可怕的模式

对象将在其构造和调用init之间处于未定义状态。此外,还必须考虑使init线程安全,以及在多次调用init时使其健壮


还请注意,从c++11开始,您可以从另一个构造函数调用构造函数。因此,一个init函数消除多个构造函数可能导致的代码重复的论点不再适用。

我不这么认为。为什么你认为一个有构造函数的类不能成为另一个类的成员?您只需要外部类在其构造函数中初始化它。不需要指针或奇怪的两阶段初始化把戏。注意,您在这里调用了A的复制构造函数。很好!为了清晰起见,我将其更改为一个简单的构造函数:哦,这实际上是正确的方法。我很高兴我没有使用init方法编写太多的类。非常感谢。需要处理多次调用init的情况是一个很好的观点。你能解释一下为什么构造器更适合线程安全吗?