【问题标题】:A member variable's initialization must be deferred. What is(are) the best design choice(s) for this class?必须推迟成员变量的初始化。这个类的最佳设计选择是什么?
【发布时间】:2018-02-10 22:55:46
【问题描述】:

假设我们有

class Foo
{
public:
    Foo(A a, B b);
    //other member functions and variables
}

class Bar
{
public:
    Bar();
private:
    Foo foo;
    //other member variables
}

理想情况下,class Bar 的成员 foo 应该使用初始化列表进行初始化。但是,如果foo 的初始化依赖于Bar 的构造函数中的某些操作,则初始化列表将不是一个选项。而且由于foo 必须在进入Bar 的构造函数之前进行初始化,那么这里最好的设计选择是什么?

我四处搜索,发现了一些选项,比如有一个 std::unique_ptr<Foo> pfoo; (Best practice for deferred initialization of private class members),但不知何故,我觉得这个设计很草率。

我想尽可能避免使用原始指针Foo *

提前感谢您的意见!

【问题讨论】:

  • @FrançoisAndrieux 我可以在只支持 C++14 的编译器上使用什么? :)
  • "依赖于 Bar 的构造函数中的一些操作,初始化列表不是一个选项。".如果您想在构造函数中执行此操作,则可以更改代码以允许这样做。
  • 您可以调用一个返回初始化列表中的值的函数。有时这是一种从构造函数中提升逻辑代码块的便捷方法,以便您更早地初始化成员。
  • foo 依赖于 Bar 的构造函数中的某些操作”和“foo 必须在进入 Bar 的构造函数之前初始化”似乎相互矛盾。

标签: c++ c++11 constructor c++14


【解决方案1】:

有问题的可以替换:

class Bar
{
public:
    Bar()
    {
        const Data& data = ComplexFunction();
        // How initialize foo ?
    }
private:
    Foo foo;
    //other member variables
};

通过类似的方式:

class Bar
{
public:
    Bar() : Bar(ComplexFunction()) {} // Delegate constructor

private:
    Bar(const Data& data) : foo(data.a, data.b) {}

private:
    Foo foo;
    //other member variables
};

如果你真的想推迟Foo 的构造(使用两步初始化), 我会使用optionalboost 一个,如果 std 一个不适合你(C++17))。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-04
    • 2020-05-31
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2015-07-03
    相关资源
    最近更新 更多