I have a class which accepts an interface:
class interface {
public:
virtual ~interface() = default;
virtual void foo() = 0;
};
class user {
interface& impl_;
public:
user(interface& impl) : impl_(impl) {}
void foo_user() { impl_.foo(); }
};
One of the implementations of this interface is required to be a singleton for third-party reasons. I also have a simulated implementation, which has no need to be a singleton:
#include <cstdio>
class singleton_impl : public interface {
singleton_impl() = default;
public:
static singleton_impl& instance() {
static singleton_impl i;
return i;
}
void foo() override { std::printf("foo\n"); };
};
class mock_impl : public interface {
void foo() override { std::printf("mock foo\n"); };
};
Whoever uses user
needs to provide one of those, based on some runtime criteria:
#include <cstring>
int main(int argc, char** argv) {
bool is_sim = argc > 1 && strcmp(argv[1], "--sim") == 0;
interface* impl = nullptr;
if (is_sim)
impl = new mock_impl;
else
impl = &singleton_impl::instance();
user u{*impl};
u.foo_user();
if (is_sim) delete impl;
return 0;
}
What's the simplest way to avoid the raw pointer/delete here, while avoiding turning mock_impl
into a singleton itself (my current solution)? I want some kind of smart pointer that either owns or doesn't own its underlying object.
I could also always construct the mock object and then just conditionally pass it to the user
, but I feel that I shouldn't need to keep a random object around.