Let's say I have flawed C++ code like this:
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 should be-a B, so it inherits from it. But to initialize a B, we need an instance of A. C has to provide one, but how? In the above code, a is used uninitialized, because bases are initialized before members. I need to somehow initialize A before B.
If A wasn't final, I could inherit privately from A:
struct C : private A, public B {
C()
: B(*this) {}
};
But because it's final, I do this:
namespace detail {
struct C_Base {
protected:
A a;
};
}
struct C : private detail::C_Base, public B {
C()
: B(detail::C_Base::a) {}
};
Or I could use weird hacks like this:
struct C : B {
C(const A a = A())
: B(a),
a(a) {}
A a;
};
Is there a better way to do this?
You could do it with a private constructor and a pointer:
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;
};
This will ensure that
A is fully constructed before constructing BA is only constructed once and not copiedm_aPtr will stay valid for the lifetime of the class (due to const) and will destroy A on class destruction properly (like an instanced member)m_a with the same syntax as an instanced member, because it's a reference. If it's ok for you, you could also leave m_a away and work only with the pointer m_aPtr.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With