Reputation: 16402
I have an interface:
struct result {
virtual ~result() = 0;
virtual auto getName() -> std::string = 0;
protected:
result() = default;
result(const result &) = default;
auto operator=(const result &) -> result & = default;
}
and an implementation:
struct abstract_result : public result {
auto getName() -> std::string override;
std::string m_name;
}
I'm currently using an instance of abstract_result
within my code to be populated by a number of algorithms but I want the end user to receive a pointer to the interface so I can hide the implementation.
How can I turn an instance of abstract_result
into a std::unique_ptr<result>
?
Upvotes: 0
Views: 90
Reputation: 131475
If I understand you correctly, what you want to do is pretty similar to what @user463035818 says, but with the populated structure, i.e.:
std::unique_ptr<result> pointer_to_result {&my_populated_abstract_result };
And this is fine since, again, an abstract_result
is-a result
. But you might not want to do this at all if your my_populated_abstract_result
is not dynamically allocated. std::unique_ptr is not generally intended for use with objects on the stack (e.g. local variables). If my_populated_abstract_result
is a local variable - don't put in a unique_ptr
at all (nor in an std::shared_ptr
), and don't try to hold on to it once my_populated_abstract_result
goes out of scope.
PS :
abstract_result
, with the concrete classes being foo_result
, bar_result
, baz_result
? _result
in them? That way you'll have result::abstract
(or result::base
) and then result::foo
, result::bar
, result::baz
.Upvotes: 2
Reputation: 122133
An abstract_result
is-a result
(btw your naming seems to be the wrong way around) so a pointer to a abstract_result
is-a pointer to a result
. So you just need to construct the unique_ptr
, eg
auto x = unique_ptr<result>(new abstract_result());
In case the instance is on the stack and you are worried about unique_ptr
trying to delete an instance with automaitc storage, you can use a deleter that does nothing, as in
template <typename T>
struct no_deleter {
void operator()(T*){}
};
abstract_result x;
std::unique_ptr<result> x_ptr{ &x, no_deleter<result>() };
However, in that case I wonder why you want to use a unique_ptr
in the first place. There is nothing wrong about using raw pointers as long as they do not own the object (ie whoever holds the pointer is not responsible for deleting the object), while a unique_ptr
is usually meant to own the object it points to.
PS
I have to admit that I dont fully understand what is your problem...
but I want to turn a populated instance of abstract_result into a pointer to result
As mentioned above, a pointer to a abstract_result
is (sloppy-speaking) already a pointer to a result
. A simpler example:
abstract_result x;
result* pointer_to_result = &x;
Upvotes: 3