让我们说我这样的C ++代码有缺陷:
struct A final {
A(); // Initializes somethingShared
shared_ptr<Something> somethingShared;
};
struct B {
B(const A& a);
};
struct C : B {
C()
: B(a) {} // Uh-oh
A a;
};
C
应是 B
,因此它会从中继承。但要初始化B
,我们需要一个A
的实例。 C
必须提供一个,但如何?在上面的代码中,a
未初始化使用,因为base在成员之前初始化。我需要在A
之前以某种方式初始化B
。
如果A
不是 final
,我可以私下从A
继承:
struct C : private A, public B {
C()
: B(*this) {}
};
但是因为它是final
,我这样做:
namespace detail {
struct C_Base {
protected:
A a;
};
}
struct C : private detail::C_Base, public B {
C()
: B(detail::C_Base::a) {}
};
或者我可以使用这样的怪异黑客:
struct C : B {
C(const A a = A())
: B(a),
a(a) {}
A a;
};
有更好的方法吗?
答案 0 :(得分:1)
您可以使用私有构造函数和指针来执行此操作:
class C : B {
private:
const std::unique_ptr<A> m_aPtr;
C(A* a) : B(*a) , m_aPtr(a), m_a(*a){}
public:
C() : C(new A()) {}
A& m_a;
};
这将确保
A
在构建B
A
仅构建一次而不是复制m_aPtr
将在课程的生命周期内保持有效(由于const
)并且会在类毁坏时正确销毁A
(如实例成员)m_a
语法与实例成员相同,因为它是一个引用。如果它对您没问题,您也可以离开m_a
并仅使用指针m_aPtr
。