How do I setup a class that represents an interface? Is this just an abstract base class?
Make a class with pure virtual methods. Use the interface by creating another class that overrides those virtual methods.
A pure virtual method is a class method that is defined as virtual and assigned to 0.
class IDemo
{
public:
virtual void OverrideMe() = 0;
}
class Child : public IDemo
{
public:
virtual void OverrideMe()
{
//do stuff
}
}
The whole reason you have a special Interface type-category in addition to abstract base classes in C#/Java is because C#/Java do not support multiple inheritance.
C++ supports multiple inheritance, and so a special type isn't needed. An abstract base class with no non-abstract (pure virtual) methods is functionally equivalent to a C#/Java interface.
To expand on the answer by bradtgmurray, you may want to make one exception to the pure virtual method list of your interface by adding a virtual destructor. This allows you to pass pointer ownership to another party without exposing the base class. The destructor doesn't have to do anything, because the interface doesn't have any concrete members. It might seem contradictory to define a function as both virtual and inline, but trust me - it isn't.
class IDemo
{
public:
virtual ~IDemo() {}
virtual void OverrideMe() = 0;
};
class Parent
{
public:
virtual ~Parent();
};
class Child : public Parent, public IDemo
{
public:
virtual void OverrideMe()
{
//do stuff
}
};
There is no concept of "interface" per se in C++. AFAIK, interfaces were first introduced in Java to work around the lack of multiple inheritance. This concept has turned out to be quite useful, and the same effect can be achieved in C++ by using an abstract base class.
An abstract base class is a class in which at least one member function (method in Java lingo) is a pure virtual function declared using the following syntax:
class A
{
virtual void foo() = 0;
};
An abstract base class cannot be instantiated, i. e. you cannot declare an object of class A. You can only derive classes from A, but any derived class that does not provide an implementation of foo()
will also be abstract. In order to stop being abstract, a derived class must provide implementations for all pure virtual functions it inherits.
Note that an abstract base class can be more than an interface, because it can contain data members and member functions that are not pure virtual. An equivalent of an interface would be an abstract base class without any data with only pure virtual functions.
And, as Mark Ransom pointed out, an abstract base class should provide a virtual destructor, just like any base class, for that matter.
A little addition to what's written up there:
First, make sure your destructor is also pure virtual
Second, you may want to inherit virtually (rather than normally) when you do implement, just for good measures.
You can also consider contract classes implemented with the NVI (Non Virtual Interface Pattern). For instance:
struct Contract1 :: boost:noncopyable
{
virtual ~Contract1();
void f(Parameters p) {
assert(checkFPreconditions(p)&&"Contract1::f, pre-condition failure");
// + class invariants.
do_f(p);
// Check post-conditions + class invariants.
}
private:
virtual void do_f(Parameters p) = 0;
};
...
class Concrete : public Contract1, public Contract2
{
private:
virtual void do_f(Parameters p); // From contract 1.
virtual void do_g(Parameters p); // From contract 2.
};
My answer is basically the same than others but I think there is two other important things to do:
- declare a virtual destructor in your interface or make a protected non virtual one to avoid undefined behaviours if someone try to delete an objet of type "IDemo".
- Use virtual inheritance to avoid problems whith multiple inheritance. (There is more often multiple inheritance when we us interfaces)
And like other answers:
- Make a class with pure virtual methods.
Use the interface by creating another class that overrides those virtual methods.
class IDemo { public: virtual void OverrideMe() = 0; virtual ~IDemo() {} }
Or
class IDemo
{
public:
virtual void OverrideMe() = 0;
protected:
~IDemo() {}
}
And
class Child : virtual public IDemo
{
public:
virtual void OverrideMe()
{
//do stuff
}
}
All good answers above. One extra thing you should keep in mind - you can also have a pure virtual destructor. The only difference is that you still need to implement it.
Confused?
--- header file ----
class foo {
public:
foo() {;}
virtual ~foo() = 0;
virtual bool overrideMe() {return false;}
};
---- source ----
foo::~foo()
{
}
The main reason you'd want to do this is if you want to provide interface methods, as I have, but make overriding them optional.
To make the class an interface class requires a pure virtual method, but all of your virtual methods have default implementations, so the only method left to make pure virtual is the destructor.
Reimplementing a destructor in the derived class is no big deal at all - I always reimplement a destructor, virtual or not, in my derived classes.
If you're on Windows then you could do the following:
struct __declspec(novtable) IFoo
{
virtual void Bar();
};
class Child : public IFoo
{
public:
virtual void Bar() { /* Do Something */ }
}
I like this approach because it results in a lot smaller interface code and the generated code size can be significantly smaller. The use of novtable removes all reference to the vtable pointer in that class, so you can never instantiate it directly. See the documentation here - novtable.