使用 init-methods 来避免使用 new 分配对象——这是糟糕的设计吗?

Using init-methods to avoid allocating object using new - is this bad design?

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

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

而不是:

Class A {
public:
A(int number);
};

这允许我像这样在其他 类 中使用 A 作为成员:

class B {
A m_a;
};

而不是我以前的做法:

class B {
A *m_a;
};

(然后在 B 的构造函数中分配 m_a。)

使用 init 函数的好处是我不必担心删除 m_a 因为它会在 B 的实例被销毁时被销毁。

我的问题是:使用初始化方法是否有任何我应该知道的缺点?这会溢出堆栈等吗?

到目前为止一切正常,但我认为在以这种方式编写大量代码之前我应该​​先询问一下。

您不必使用指针将 class 个实例作为属性。

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
}

m_a会在B的实例被销毁时被销毁。

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

即使需要非默认构造函数来实例化属性,也可以按值存储属性。在 class B 的构造函数中,您需要通过初始化列表显式实例化 m_a,例如B(int number):m_a(number){}。使用初始化函数来克服这个问题"problem"在这里真的没有必要,因为语言本身就支持这个。

这是一个可怕的模式。

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

另请注意,从 c++11 开始,您可以从另一个构造函数调用构造函数。因此,关于 init 函数消除了可能因具有多个构造函数而产生的重复代码的论点不再适用。