![](/img/trans.png)
[英]How to initialize a tuple of non-default-constructible not-copyable objects?
[英]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模式的方式,这种模式可能非常有用,例如,您并不总是需要所有复杂的计算。
这假定所有类都是可复制构造的,但您可以或多或少地轻松地修改它以支持您所需的类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.