How do I setup a class that represents an interface? Is this just an abstract base class?
相关问题
- Sorting 3 numbers without branching [closed]
- How to compile C++ code in GDB?
- Why does const allow implicit conversion of refere
- thread_local variables initialization
- What uses more memory in c++? An 2 ints or 2 funct
相关文章
- List可以存储接口类型的数据吗?
- Class layout in C++: Why are members sometimes ord
- How to mock methods return object with deleted cop
- Which is the best way to multiply a large and spar
- C++ default constructor does not initialize pointe
- Selecting only the first few characters in a strin
- What exactly do pointers store? (C++)
- Converting glm::lookat matrix to quaternion and ba
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:
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.
You can also consider contract classes implemented with the NVI (Non Virtual Interface Pattern). For instance:
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?
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.
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.
In C++11 you can easily avoid inheritance altogether:
In this case, an Interface has reference semantics, i.e. you have to make sure that the object outlives the interface (it is also possible to make interfaces with value semantics).
These type of interfaces have their pros and cons:
Finally, inheritance is the root of all evil in complex software design. In Sean Parent's Value Semantics and Concepts-based Polymorphism (highly recommended, better versions of this technique are explained there) the following case is studied:
Say I have an application in which I deal with my shapes polymorphically using the
MyShape
interface:In your application, you do the same with different shapes using the
YourShape
interface:Now say you want to use some of the shapes that I've developed in your application. Conceptually, our shapes have the same interface, but to make my shapes work in your application you would need to extend my shapes as follows:
First, modifying my shapes might not be possible at all. Furthermore, multiple inheritance leads the road to spaghetti code (imagine a third project comes in that is using the
TheirShape
interface... what happens if they also call their draw functionmy_draw
?).Update: There are a couple of new references about non-inheritance based polymorphism:
While it's true that
virtual
is the de-facto standard to define an interface, let's not forget about the classic C-like pattern, which comes with a constructor in C++:This has the advantage that you can re-bind events runtime without having to construct your class again (as C++ does not have a syntax for changing polymorphic types, this is a workaround for chameleon classes).
Tips:
click
in your descendant's constructor.protected
member and have apublic
reference and/or getter.if
s vs. state changes in your code, this might be faster thanswitch()
es orif
s (turnaround is expected around 3-4if
s, but always measure first.std::function<>
over function pointers, you might be able to manage all your object data withinIBase
. From this point, you can have value schematics forIBase
(e.g.,std::vector<IBase>
will work). Note that this might be slower depending on your compiler and STL code; also that current implementations ofstd::function<>
tend to have an overhead when compared to function pointers or even virtual functions (this might change in the future).