Reputation: 316
I'm trying to convert a c# project to c++. I'm trying the following:
class IDocInterface
{
public:
// implemented in CSpecificDoc
virtual bool CreateDoc() = 0;
// implemented in COperations
virtual void AddOperation() = 0;
// implemented in CDoc
virtual void Save() = 0;
};
class COperations
{
public:
void AddOperation() {}; // implementation for CDoc and derivates
};
class CDoc : public IDocInterface, public COperations
{
public:
void Save() {}; // implemented here
};
class CSpecificDoc : public CDoc
{
public:
bool CreateDoc() {}; // implemented here
};
When I try to do:
IDoc * pDoc = new CSpecificDoc();
I get error c2259 cannot intantiate abstract class due to folloing members: void IDocInterface::AddOperations() is abstract.
Don't know what I'm missing.
My inheritance structure works fine like this in c# where i use "interface IDocInterface" and "abstract class CDoc".
Solution:
Added:
class IOperations
{
public:
virtual void AddOperation() = 0;
}
Then change above to:
class IDocInterface : public virtual IOperations
{
public:
// implemented in CSpecificDoc
virtual bool CreateDoc() = 0;
// implemented in CDoc
virtual void Save() = 0;
};
and
class COperations : public virtual IOperations
Still, I think its a bit strange that the whole thing worked so nicely in C# without the IOperations class...
Upvotes: 2
Views: 264
Reputation: 726599
Unless COperations
inherits IDocInterface
, its AddOperations()
member function is not considered related in any way to the virtual function with the same signature defined inside IDocInterface
. In this case, C++ compiler will complain about a missing implementation.
However, inheriting IDocInterface
in COperations
would create multiple paths of inheriting the same member function. This may be a problem, because functions, even the pure virtual ones, which are inherited through different paths are considered different (this is in sharp contrast to Java and C#'s implementations of interfaces). You fix this problem by marking your inheritance virtual
, like this:
class IWithOperations {
public:
// implemented in COperations
virtual void AddOperation() = 0;
};
class IDocInterface : public virtual IWithOperations
{
public:
// implemented in CSpecificDoc
virtual bool CreateDoc() = 0;
// implemented in CDoc
virtual void Save() = 0;
};
class COperations : public virtual IWithOperations
{
public:
void AddOperation() {}; // implementation for CDoc and derivates
};
class CDoc : public virtual IDocInterface, public virtual COperations
{
public:
void Save() {} // implemented here
virtual bool CreateDoc() = 0; // must be overridden
};
class CSpecificDoc : public virtual CDoc
{
public:
bool CreateDoc() {} // implemented here
};
Here is a demo on ideone.
Upvotes: 5
Reputation: 1426
With your declaration of IDocInterface
, you cannot instanciate a subclass that does not contain all CreateDoc
, AddOperation
and Save
.
You need to reimplement them all, otherwise the class will be considered as an abstract class that needs to be inherited from to be used.
If you wanted to have optional member functions in your interface, you can declare them like that:
virtual bool CreateDoc() {} // note that you don't need to add ; here
And reimplement it where necessary
class CDoc : public IDocInterface, public COperations
{
public:
// virtual is optional here but usually good for documentation (you can use override keyword instead if using C++11)
virtual bool CreateDoc() { /* Default implementation */ }
}
class CSpecificDoc : public CDoc
{
public:
bool CreateDoc() { /* CSpecificDoc implementation */ }
}
It may be a typo but your COperations
class doesn't inherit from IDocInterface
, the compiler will not consider the AddOperation
method as an implementation of the one in IDocInterface
. As @dasblinkenlight said in his answer, you will have multiple IDocInterface
inheritance and will have to use the virtual keyword to avoid having several IDocInterface
. This is called inheriting in diamond I think (at least it was presented to us like that at uni).
class COperations: public IDocInterface
{
public:
void AddOperation() {} // implementation for CDoc and derivates
}
Upvotes: 0
Reputation: 1021
My guess is you need to re-implement AddOperation in CDoc so it knows it's the same as the abstract one in the interface:
class CDoc : public IDocInterface, public COperations
{
public:
Save() {} // implemented here
virtual bool CreateDoc() = 0; // must be overridden
void AddOperation() {
COperations::AddOperation();
}
}
or you can use the using statement in c++11...
Upvotes: 0