Reputation: 151
I have the following problem. I have a class, which has the function
std::shared_ptr<IBaseInterface> getBaseInterface()
{
return m_spBase;
}
I also have the following:
private:
std::shared_ptr<IBaseInterface> m_spBase;
XMLReader* m_xmlReader;
std::unique_ptr<DerivedInterface> m_xmlInterface;
The thing here is that DerivedInterface
inherits from IBaseInterface
, so from the outside, it should be visible as IBaseInterface
. I should also mention that m_xmlInterface does not have to be a pointer(unique/not unique) here. Also, DerivedInterface is a concrete class which has the following constructor(this may be less important for my question):
DerivedInterface( XMLReader* pxmlReader );
IBaseInterface is just a pure abstract class which has some pure virtual functions which DerivedInterface defines.
Now, I want to create an instance of DerivedInterface and use getBaseInterface
to return it as a IBaseInterface
, that is my main point. I try to do something like this in the constructor of the class:
m_xmlInterface = std::unique_ptr<DerivedInterface>(
new DerivedInterface( m_xmlReader ) );
m_spBase = std::move( m_xmlInterface );
But this does not work(I assume that you cannot move one type of pointer to another, even if the class that one pointer points to inherits from the other). I would be glad if anyone gave any suggestions on how to do this.
Upvotes: 1
Views: 1847
Reputation: 3939
Think about the ownership semantics of what you want to achieve and advertise to the users of your class and functions first, then choose the implementation and types that fit it.
From what you write you seem to want to share ownership of m_xmlInterface
between an object of your class and the users of it. Meaning, if a user gets the interface, it still owns it when the object of your class goes away. In this case you should store it as a shared pointer in your class and return it as a shared pointer, too. In this case you would have:
std::shared_ptr<DerivedInterface> m_xmlInterface;
and: simply:
std::shared_ptr<IBaseInterface> getBaseInterface()
{
return m_xmlInterface;
}
No need to go through another variable. Here is a full example that shows this work:
#include <memory>
struct A {};
struct B : public A {};
class Foo {
public:
Foo() {}
std::shared_ptr<A> get() { return mB; }
private:
std::shared_ptr<B> mB;
};
int main() {
auto foo = Foo{};
auto a = foo.get();
}
If you want ownership to stay strictly with your class, you could store it as a unique_ptr
. The only way you can then give access is by returning a raw pointer or a reference (probably preferable), except for when you want to make it possible for your class to relinquish ownership, in which case you should use move
. It is then best not to return a shared pointer, but still a unique pointer, this gives the caller freedom to decide themselves if they want to then share it afterwards or not. In this case you would have:
std::unique_ptr<DerivedInterface> m_xmlInterface;
and:
std::unique_ptr<IBaseInterface> getBaseInterface()
{
return std::move(m_xmlInterface);
}
However big N.B.: after anybody calls this function, your class can not use m_xmlInterface
anymore, it lost all ownership of it.
Upvotes: 6