What is a way to define a member object variable of a class that can either be
Basically I would like to have something like this (which does not compile due to trying to bind non-const lvalue reference to temporary):
class A;
class B{
public:
B() : m_a { A() } {} // <- does not compile because A() is temporary
B(A& a) : m_a { a } {}
useA() { m_a.do_something(); }
private:
A& m_a;
};
const
reference is not an option, since I need access to non-const
methods of the object.
std::unique_ptr
is not an option, because ownership shall stay with the caller of the class's constructor.
Is one of these following options the most reasonable thing to do or is there a better way? Both seem kind of weird. Creating an object m_aObj
that is not at all used if the second constructor is used. And using shared_ptr
s even though I do not want to keep ownership necessarily.
class A;
class B{
public:
B() : m_a { m_aObj } {}
B(A& a) : m_a { a } {}
useA() { m_a.do_something(); }
private:
A& m_a;
A m_aObj;
};
class A;
class B{
public:
B() : m_a { std::make_shared<A>() } {}
B(std::shared_ptr<A> a) : m_a {a} {}
useA() { m_a->do_something(); }
private:
std::shared_ptr<A> m_a;
};
You can combine a reference A&
with an optional internal std::optional<A>
.
class B{
public:
B()
: m_internal_a{ std::in_place } // Create the internal A
, m_a { *m_internal_a } // ... and reference it
{
}
B(A& a)
: m_internal_a{ std::nullopt } // Omit the internal A
, m_a { a } // ... and reference the external one.
{
}
void useA() { m_a.do_something(); }
private:
std::optional<A> m_internal_a; // Used only when A is internal
A& m_a;
};