Consider the following setup:
struct Base {
virtual void f() = 0;
virtual ~Base() {};
};
struct Helper: Base {
virtual void f() {}
};
struct Derived: public Base {
Derived(Helper& helper): m_helper(helper) {}
void f() {}
Helper& m_helper;
};
that I, at the moment, use conditionally using preprocessor:
Helper h;
#if condition
Derived d(h);
#else
Helper& d(h);
#endif
If you wish, Derived
is a class that enhances Helper
.
Now, how can I do that dynamically, at best as little error-prone as possible?
std::unique_ptr<Base> p = new Helper();
if(condition){
p = new Derived(*helper);
}
won't work, I guess, because on the assignment p = new Derived
, I will cause deletion of the original Helper
, won't I?
Of course, I can simply do something like
Helper h;
std::optional<Derived> d = condition ? Derived(h) : {};
Base& p = d ? d : h;
Or, go fully manually, and do
Helper h;
Derived* d = condition ? new Derived(h) : 0;
Base& p = d ? *d : h;
...
if(d) delete d;
None of these solutions really pleases me. What is the advisable way?
You can use std::shared_ptr
instead of std:unique_ptr
:
auto h = std::make_shared<Helper>();
std::shared_ptr<Base> p;
if (condition) {
p = std::make_shared<Derived>(*h);
} else {
p = h;
}
Alternatively:
auto h = std::make_shared<Helper>();
auto p = condition ? std::shared_ptr<Base>(new Derived(*h)) : h;
Though, I would suggest sticking with the std::optional
approach you proposed, as it doesn't rely on dynamic allocation. However, what you showed won't compile, but this does:
Helper h;
std::optional<Derived> d;
if (condition) d.emplace(h);
Base& p = d ? *d : static_cast<Base&>(h);