I have the following class structure:
class DBData
{
public:
DBData();
virtual
~DBData() = 0;
virtual
DBData* Clone() const = 0;
virtual
std::unique_ptr<DBData>& Clone() const = 0;
};
This does no compile, and the compiler objects with the following error message:
error: ‘virtual std::unique_ptr<DBData>& DBData::Clone() const’ cannot be overloaded with ‘virtual DBData* DBData::Clone() const’
Why does this error occur? My guess would be that it has something to do with both return types being either references or pointers (which are in some ways similar).
Or possibly unique_ptr
is too similar to a raw pointer, but that doesn't seem to make a lot of sense to me.
Obvious Solution:
Obvious problem obvious solution. Should have realized this. Taking inspiration from operator++
:
virtual
std::unique_ptr<DBData>& Clone(int dummy = 0) const = 0;
Or perhaps better, just rename it:
virtual
std::unique_ptr<DBData>& CloneUniquePtr() const = 0;
Edit: Nope - this doesn't work either.
The reason being that this
virtual
std::unique_ptr<DBDataDerived>& CloneUniquePtr() const;
is an invalid covariant return type
. Given that this is a reference type, I thought this should be ok. Is it the case that only raw pointers can be covariant return types?
Edit 2: For a type to be covariant (in this context at least) it has to obey Liskov Substitution Principle.
It seems the only way to write something compilable is to do:
std::unique_ptr<DBData> DBDataDerived::Clone() const;
Which means not using covariant return types at all.