【问题标题】:Why cant we delay initialise a class member with a non default constructor?为什么我们不能延迟使用非默认构造函数初始化类成员?
【发布时间】:2020-05-26 13:33:42
【问题描述】:

我有一个像下面这样的课程:

#pragma once
#include <atomic>

class MyClassAnother {
public:
    MyClassAnother(int val) : m_val(val) {
    }

private:
    int m_val;
};

还有一个类持有MyClassAnother的对象

#pragma once
#include "MyClassAnother.hpp"

class MyClass {
public:
    MyClass() {

    }

    void Func() {
        anotherClassObject = MyClassAnother(2);
    }

private:
    MyClassAnother anotherClassObject;
};

这里是main.cpp

#include "MyClass.hpp"
#include <iostream>

int main() {
   MyClass object;
}

当然程序不会编译。而且是因为下面的错误

错误:“MyClass”的构造函数必须显式初始化成员 'anotherClassObject' 没有默认值 构造函数

问题:
但为什么?为什么我不能延迟初始化类成员?是否有一个默认构造函数并延迟使用真正的构造函数初始化它?那么这样做是不是一种反模式呢?

我知道这可以通过将MyClassAnother anotherClassObject 设为指针来解决。但在这种情况下,我希望将MyClassAnother anotherClassObject 作为成员对象或引用成员。

【问题讨论】:

    标签: c++11 constructor default-constructor


    【解决方案1】:

    构造函数必须保证所有成员都被正确地构造和初始化,而这个不这样做。如果您忘记拨打Func() 然后访问objcect.anotherClassObject 会怎样?

    延迟初始化通常可以被认为是一种反模式,并且违反了RAII idiom,它指出当且仅当底层资源的初始化(在这种情况下为MyClassAnother)成功时,对象构造才应该成功。这是一个很好的模式,因为它可以防止周围出现不可用的对象,因为它们未能正确初始化,或者因为有人忘记执行他们延迟的初始化步骤。

    如果MyClass 对象在没有MyClassAnother 实例的情况下实际上可用,则可以将后者包装在std::unique_pointer (C++11) 或std::optional (C++17) 中。

    如果MyClass 对象在没有MyClassAnother 实例的情况下不可用,则需要将该实例传递给构造函数,或者在构造函数的初始化列表中创建它。

    【讨论】:

      猜你喜欢
      • 2011-08-09
      • 2018-11-24
      • 2015-07-03
      • 1970-01-01
      • 2020-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多