如何正确初始化不可默认构造的类成员
How to properly initialize non-default-constructible class member?
假设我定义了一个类Foo
,它没有实现默认构造函数。此外,我有一个类Bar
,它"拥有"Foo
的实例:
class Foo() {
private:
int m_member;
public:
Foo( int value ) : m_member(value) { }
};
class Bar() {
private:
Foo m_foo;
public:
Bar( /* ... */ ) {
int something;
/* lots of code to determine 'something' */
/* should initialize m_foo to 'Foo(something)' here */
}
};
所示的代码将无法运行,因为Bar
正在尝试调用Foo
的默认构造函数。
现在我要做的是让Bar
的构造函数首先确定something
,然后将结果传递给Foo
的构造函数。
解决这个问题的一种方法是让Bar
只拥有一个指向Foo
的引用/指针,并在m_something
确定后初始化它。然而,我想避免这种情况,以明确m_foo
的生命周期完全依赖于拥有类的生命周期。
另一种方法是在Foo
中实现默认构造函数并稍后设置值,这也是我想避免的,因为Foo
的任何实例(在任何时候)都应该有其成员的有效值。
实现这一点的正确方法是什么?我在这里被引用/指针卡住了吗?
最好的方法是创建辅助函数,它将计算一些东西,然后在构造器初始化列表中初始化m_foo
。
class Bar {
private:
Foo m_foo;
public:
Bar( /* ... */ ) : m_foo(calculate_something()) {
}
private:
static int calculate_something()
{
int something = 0;
// lot of code to calculate something
return something;
}
};
这个复杂的初始化代码实际上属于 Bar
吗?最好考虑使用一个单独的类来完成初始化。就像
class Bar {
public:
Bar(int param, Foo foo): m_foo(foo) {
// do just some very simple calculations, or use only constructor initialization list
}
...
}
class BarBuilder {
public:
BarBuilder(/*...*/) {
// do all calculations, boiling down to a few parameters for Bar and Foo
Foo foo(fooParameter);
m_result = new Bar(barParameter, foo); // give Foo here explicitly
}
Bar getResult() { return *m_result; }
private:
Bar* m_result; // or better use unique_ptr
}
这也为一个完整的Builder模式打开了道路,在某些情况下,例如,您并不总是需要所有复杂的计算。
这假定所有的类都是可复制构造的,但是您可以或多或少地修改它以支持您需要的内容。
相关文章:
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- C++向量默认为成员参数
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 强制使用默认构造函数对成员进行未初始化的声明
- 在 C++ 中,默认情况下构造函数为类的数据成员提供的值是多少?
- 用作默认参数的静态成员会导致无法解析的外部
- 为什么在使用指针时不采用类成员的默认值,而不是直接实例化对象时?
- 具有外部定义的默认特殊成员函数
- C++中未初始化成员布尔变量的默认值是多少?
- 两个成员,在Base中默认初始化,可能在Derived中非默认初始化
- 声明成员对象而不调用其默认构造函数
- 将私有数据成员作为默认参数传递给该类的公共方法时出错
- 结构中的默认成员值或默认构造函数参数
- C++11 默认类成员初始化与初始值设定项列表同时
- POD成员默认初始化无括号
- 初始化类成员 - 默认值还是成员初始化列表?
- 具有类成员默认值的 C++11 默认构造函数行为
- 模板成员默认初始化
- 类 POD 成员默认初始化与零初始化与无初始化