Consider the following program
class Node {
public:
virtual void Visit() = 0;
};
class Graph {
public:
virtual void Visit();
};
class GraphNode1 : public Node, Graph {
};
class GraphNode2 : public Node, Graph {
using Graph::Visit;
};
class GraphNode3 : public Node, Graph {
public:
virtual void Visit() {
Graph::Visit();
}
};
int main()
{
GraphNode1 a;
GraphNode2 b;
GraphNode3 c;
}
It does not compile, but complains that GraphNode1 and GraphNode2 are abstract, since Node::Visit is pure virtual.
I would have assumed that both GraphNode1 and GraphNode2 were fine, since:
They contain an implementation of Visit.
They contain only a single implementation of Visit, so there should be no ambiguity.
Can anyone explain why I have to create an explicit implementation to make it work.
Node and Graph are unrelated classes. Which makes Node::Visit and Graph::Visit distinct unrelated member functions.
Neither can override the other. You seem to think Graph::Visit is somehow "better" than Node::Visit on account of not being pure virtual, and should therefore override it. But there is no objective reason for it. For starters, pure virtual functions can have a definition:
struct A {
virtual void thing() = 0;
};
inline void A::thing() {}
And secondly, a function can be made pure virtual when overriden:
struct A {
virtual void thing() {}
};
struct B : A {
void thing() override = 0;
};
So really, there is no reason for Node::Visit and Graph::Visit to interact as overriders of each other. That's why you need to be explicit and define a function yourslef that will serve as an overrider*.
* One shortcoming of C++ is that you in fact override both Node::Visit and Graph::Visit in GraphNode3. IMO it's a quirk of the language (really, it should be possible to keep them unrelated). MSVC has an extension that lets you choose what to override in a more fine-grained manner.
Related
Let's assume you have an base class for the different states of a State Machine that has methods for different inputs like mouse, keyboard, joystick, etc. Now not every derived state is going to use all possible types of inputs. If the base class methods are pure virtual every derived state class needs to always implement every single one of them. To avoid this i declared them with an empty body in the base class and just override the ones that are used by the particular derived class. In case the class doesn't use a certain input type the empty base class method get's called. I am storing the currentState in a base class pointer and just feed it with the input without having to know which particular derived state it actually is to avoid unnessecary casts.
class Base
{
public:
virtual void keyboardInput() {}
virtual void mouseInput() {}
};
class Derived : public Base
{
public:
void keyboardInput()
{
// do something
}
// Derived doesnt use mouseInput so it doesn't implement it
};
void foo(Base& base)
{
base.keyboardInput();
base.mouseInput();
}
int main()
{
Derived der;
foo(der);
}
Is this considered a good practice?
Your question is opinion based, but I'd rather follow this approach to use an interface:
struct IBase {
virtual void keyboardInput() = 0;
virtual void mouseInput() = 0;
virtual ~IBase() {}
};
class Base : public IBase {
public:
virtual void keyboardInput() override {}
virtual void mouseInput() override {}
};
class Derived : public Base {
public:
void keyboardInput() override {
// do something
}
// Derived doesnt use mouseInput so it doesn't implement it
};
int main() {
std::unique_ptr<IBase> foo = new Derived();
foo->keyboardInput();
foo->mouseInput();
return 0;
}
Some arguments why that's better practice added from the comments:
The idea is that interface should contain as little assertions as possible, making it less likely to change, making it more dependable for those who inherit from it. Implementing the methods, albeit empty, is already an assertion, however small.
It would be less pain for refactorings coming later, which introduce more interfaces with multiple inheritance.
It really depends on what you want from the methods. When declaring an interface, usually the methods are left pure virtual because they are required to be implemented for the class to work at all. Marking them pure virtual signals "You have to implement this.".
However, sometimes there are methods that may do nothing and it's valid for all possible implementations for them to do nothing. It is not very common, but it is possible.
I don't think that your interface is the case though, and you should follow #πάντα ῥεῖ's answer. Or do it through multiple inheritance:
class MouseInput {
public:
virtual void mouseInput() = 0;
}
class KeyboardInput {
public:
virtual void keyboardInput() = 0;
}
class Derived : public KeyboardInput
{
public:
virtual void keyboardInput() override
{
// do something
}
};
class AllInput : public KeyboardInput, public MouseInput
{
public:
virtual void keyboardInput() override
{
// do something
}
virtual void mouseInput() override
{
// do something
}
};
That has the benefit that you can have methods that explicitly say that they work with one kind of input:
void doSomethingMouseIsh(MouseInput* input);
The disadvantage is that methods that combine mouse and keyboard input get weird unless you have InterfaceAllInput as interface and use it for all "all input methods"
Final note: as long as you try to write clean code, considering each use case is more important than some best practices.
If you going to be strict about it this does violate ISP (https://en.wikipedia.org/wiki/Interface_segregation_principle) as your forcing a subclass to depend on a method it doesn't use - but generally its not too bad in practice if the alternative adds more complexity.
So I'm trying to move some common code in a few classes that implement an interface* to an abstract base class. However, the abstract base class needs to know a little bit about how the derived classes want to do things in order to determine exactly what to do. However, I'm not entirely sure if I should implement this using a pure virtual function or a protected member variable.
I'll give a simple example describing what I'm trying to do.
The interface:
class SomeInterface
{
public:
void DoSomething() = 0;
// ...
};
The abstract base class I'm trying to implement using pure virtual function:
class AbstractBase : public SomeInterface
{
public:
virtual void DoSomething()
{
for (int i = 0; i < GetNumIterations(); i++)
{
// Call implementation in derived classes, for example
DoSomethingImpl();
}
}
protected:
virtual void DoSomethingImpl() = 0;
virtual int GetNumIterations() = 0;
};
A derived class:
class Derived1 : public AbstractBase
{
protected:
virtual void DoSomethingImpl()
{
// Do actual work.
}
virtual int GetNumIterations()
{
return 5;
}
};
Another derived class:
class Derived2 : public AbstractBase
{
protected:
virtual void DoSomethingImpl()
{
// Do actual work.
}
virtual int GetNumIterations()
{
return 1;
}
};
Or the other way would be using a protected variable:
class AbstractBase
{
public:
virtual void DoSomething()
{
for (int i = 0; i < numIterations; i++)
{
// Call implementation in derived classes, for example
DoSomethingImpl();
}
}
protected:
virtual void DoSomethingImpl() = 0;
int numIterations;
};
And the derived would be like:
class Derived1 : public AbstractBase
{
public:
Derived1()
: numIterations(5)
{
}
protected:
virtual void DoSomethingImpl()
{
// Do actual work.
}
};
Same thing for Derived2.
I know there's some overhead related to virtual methods (probably insignificant, but still), and that the protected variable might not be great for encapsulation, or that it could be forgotten and left uninitialized. So my question is basically, which of these is preferrable and why, or should I avoid this scenario altogether and try to handle it differently?
Note: my actual code is a bit more complicated. I havent't actually tested to see if this code works, so forgive me if it's incorrect.
*When I say interface, I mean a class containing only pure virtual functions.
In fact, what you are trying to do is very common. However, there is one more approach to implement this which explicitly defines the contract for derivatives of AbstractBase. Modifying your example it would look as follows:
class AbstractBase : public SomeInterface
{
public:
explicit AbstractBase(int numIterations) : numIterations(numIterations) {}
virtual void DoSomething()
{
for (int i = 0; i < numIterations; i++)
{
// Call implementation in derived classes, for example
DoSomethingImpl();
}
}
protected:
virtual void DoSomethingImpl() = 0;
// Can omit it, if not needed by derivatives
int GetNumIterations() { return numIterations; }
private:
int numIterations;
};
class Derived1 : public AbstractBase
{
public:
Derived1() : AbstractBase(5) {}
protected:
virtual void DoSomethingImpl()
{
// Do actual work.
}
};
class Derived2 : public AbstractBase
{
public:
Derived2() : AbstractBase(1) {}
protected:
virtual void DoSomethingImpl()
{
// Do actual work.
}
};
As you probably understand now, by contract I meant the constructor which now explicitly forces derivatives of AbstractBase to initialize it properly, so you would never mess it. The downside of this approach is that it introduces the additional field which would be possibly duplicated among numerous copies of say Derived1 in case if this 5 never changes in your situation. So if you care about memory footprint, then I'd not go for this one. However, if numIterations can be changed, then this approach is certainly the best of the 3 proposed ones. All you'd have to do is add proper setters for it into AbstractBase.
NOTE: My approach is sort of safer and better alternative to your 2nd one as it exactly addresses the issues you've mentioned, namely encapsulation hole (redundant exposure of implementation details) and contract weakness (when you might forget to initialize numIterations because you are not forced to). Therefore, you do not want to use your 2nd approach in your current situation.
The first approach that you've proposed is good too. Its advantage over mine is that it does not introduce any memory overhead. And as long as "number of iterations" does not change you don't need to introduce a field to store it. As a result, you have to override this GetNumIterations method in every derivative, but it's OK since this is a part of (strong) contract (pure virtual method) and you can never mess it too.
To conclude, as you can see, these 2 approaches are mutually exclusive, and it is very easy to decide which one to use by simply applying their pros and cons to your particular situation.
I have a class that needs to maintain multiple (2 or 3 at the moment) contexts. These contexts are not visible outside the class. Currently I have a design as follows. Is it a good practice to use abstract class as inner classes in C++? If you have any alternatives, kindly suggest.
In the below example: The problem is, when the original Car class was written, the methods (bar1 and bar2) were written in the context of Sedan. Now I am extending the Car class by introducing a new car type (Hatchback). The algorithms in bar1 and bar2 are written for Sedan-type, and cannot be used for Hatch-back type. Unfortunately, I cannot change the existing Car class (i.e. constructor or method signatures). Therefore, I am introducing the Type class as in the example above.
Does my design approach makes sense? Please suggest better alternatives or potential problems in current design.
class Car {
public:
explicit Car(/* sedan-type */) {
// set context as Sedan
}
explicit Car(/* hatchback-type */) {
// set context as Hatchback
}
void bar1() { context_type.bar1() };
void bar2() { context_type.bar2() };
private:
class Type {
virtual void bar1() = 0;
virtual void bar2() = 0;
}
class SedanType {
void bar1() {}
void bar2() {}
}
class HatchBackType {
void bar1() {}
void bar2() {}
}
}
It's a fine practice, especially if different classes have similarly named policies and you don't want to confuse them. If you don't have a worry about that, then it sometimes it's simply less work to put them outside the class. It is rather common as a Java idiom, though.
Usually you'd only see the base inner class, if it is abstract. You absolutely should not have different constructors for Car based on them as arguments. You aren't separating your concerns and you aren't making the policy substitutable.
class Base {
public:
Base(SomeAbstractPolicy *policy);
struct SomeAbstractPolicy {
virtual ~SomeAbstractPolicy() {}
virtual void stuff() = 0;
};
};
Sometimes lazies will complain about inversion of control constructs like this. Putting the concrete policies in the same header or as static helpers in the class can be a reasonable compromise.
class Base {
public:
Base(SomeAbstractPolicy *policy);
struct SomeAbstractPolicy {
virtual ~SomeAbstractPolicy() {}
virtual void stuff() = 0;
};
static SomeAbstractPolicy *CreateAwesomeConcretePolicy();
static SomeAbstractPolicy *CreateSweetConcretePolicy();
};
You could take this a step further and use a named constructor.
class Base {
public:
Base CreateAwesomeBase();
Base CreateSweetBase();
private:
struct SomeAbstractPolicy {
virtual ~SomeAbstractPolicy() {}
virtual void stuff() = 0;
};
Base(SomeAbstractPolicy *policy);
SomeAbstractPolicy *policy;
};
Unit testing this is a lot harder, for what it's worth.
If you can't have one constructor based on your abstract policy, then the abstraction belongs in Car, not it the policy. It is usually a simpler solution when you do make this sort of change. A code smell for this is that you see methods with their entire body is a branch on the type.
Why not still extend class Car and override the bar1() and bar2() methods. In their implementations you don't have to call your parent class's methods so you will still get what you want.
For example lets take the sedan car :
class SedanCar : public Car {
public :
void bar1() {// do algorithm for sedan};
void bar2() {// do algorithm for sedan};
}
Now any instance of SedanCar with calls to bar1() or bar2() will execute the sedan implemenations.
What is the purpose of the final keyword in C++11 for functions? I understand it prevents function overriding by derived classes, but if this is the case, then isn't it enough to declare as non-virtual your final functions? Is there another thing I'm missing here?
What you are missing, as idljarn already mentioned in a comment is that if you are overriding a function from a base class, then you cannot possibly mark it as non-virtual:
struct base {
virtual void f();
};
struct derived : base {
void f() final; // virtual as it overrides base::f
};
struct mostderived : derived {
//void f(); // error: cannot override!
};
It is to prevent a class from being inherited. From Wikipedia:
C++11 also adds the ability to prevent inheriting from classes or simply preventing overriding methods in derived classes. This is done with the special identifier final. For example:
struct Base1 final { };
struct Derived1 : Base1 { }; // ill-formed because the class Base1
// has been marked final
It is also used to mark a virtual function so as to prevent it from being overridden in the derived classes:
struct Base2 {
virtual void f() final;
};
struct Derived2 : Base2 {
void f(); // ill-formed because the virtual function Base2::f has
// been marked final
};
Wikipedia further makes an interesting point:
Note that neither override nor final are language keywords. They are technically identifiers; they only gain special meaning when used in those specific contexts. In any other location, they can be valid identifiers.
That means, the following is allowed:
int const final = 0; // ok
int const override = 1; // ok
"final" also allows a compiler optimization to bypass the indirect call:
class IAbstract
{
public:
virtual void DoSomething() = 0;
};
class CDerived : public IAbstract
{
void DoSomething() final { m_x = 1 ; }
void Blah( void ) { DoSomething(); }
};
with "final", the compiler can call CDerived::DoSomething() directly from within Blah(), or even inline. Without it, it has to generate an indirect call inside of Blah() because Blah() could be called inside a derived class which has overridden DoSomething().
Nothing to add to the semantic aspects of "final".
But I'd like to add to chris green's comment that "final" might become a very important compiler optimization technique in the not so distant future. Not only in the simple case he mentioned, but also for more complex real-world class hierarchies which can be "closed" by "final", thus allowing compilers to generate more efficient dispatching code than with the usual vtable approach.
One key disadvantage of vtables is that for any such virtual object (assuming 64-bits on a typical Intel CPU) the pointer alone eats up 25% (8 of 64 bytes) of a cache line. In the kind of applications I enjoy to write, this hurts very badly. (And from my experience it is the #1 argument against C++ from a purist performance point of view, i.e. by C programmers.)
In applications which require extreme performance, which is not so unusual for C++, this might indeed become awesome, not requiring to workaround this problem manually in C style or weird Template juggling.
This technique is known as Devirtualization. A term worth remembering. :-)
There is a great recent speech by Andrei Alexandrescu which pretty well explains how you can workaround such situations today and how "final" might be part of solving similar cases "automatically" in the future (discussed with listeners):
http://channel9.msdn.com/Events/GoingNative/2013/Writing-Quick-Code-in-Cpp-Quickly
Final cannot be applied to non-virtual functions.
error: only virtual member functions can be marked 'final'
It wouldn't be very meaningful to be able to mark a non-virtual method as 'final'. Given
struct A { void foo(); };
struct B : public A { void foo(); };
A * a = new B;
a -> foo(); // this will call A :: foo anyway, regardless of whether there is a B::foo
a->foo() will always call A::foo.
But, if A::foo was virtual, then B::foo would override it. This might be undesirable, and hence it would make sense to make the virtual function final.
The question is though, why allow final on virtual functions. If you have a deep hierarchy:
struct A { virtual void foo(); };
struct B : public A { virtual void foo(); };
struct C : public B { virtual void foo() final; };
struct D : public C { /* cannot override foo */ };
Then the final puts a 'floor' on how much overriding can be done. Other classes can extend A and B and override their foo, but it a class extends C then it is not allowed.
So it probably doesn't make sense to make the 'top-level' foo final, but it might make sense lower down.
(I think though, there is room to extend the words final and override to non-virtual members. They would have a different meaning though.)
A use-case for the 'final' keyword that I am fond of is as follows:
// This pure abstract interface creates a way
// for unit test suites to stub-out Foo objects
class FooInterface
{
public:
virtual void DoSomething() = 0;
private:
virtual void DoSomethingImpl() = 0;
};
// Implement Non-Virtual Interface Pattern in FooBase using final
// (Alternatively implement the Template Pattern in FooBase using final)
class FooBase : public FooInterface
{
public:
virtual void DoSomething() final { DoFirst(); DoSomethingImpl(); DoLast(); }
private:
virtual void DoSomethingImpl() { /* left for derived classes to customize */ }
void DoFirst(); // no derived customization allowed here
void DoLast(); // no derived customization allowed here either
};
// Feel secure knowing that unit test suites can stub you out at the FooInterface level
// if necessary
// Feel doubly secure knowing that your children cannot violate your Template Pattern
// When DoSomething is called from a FooBase * you know without a doubt that
// DoFirst will execute before DoSomethingImpl, and DoLast will execute after.
class FooDerived : public FooBase
{
private:
virtual void DoSomethingImpl() {/* customize DoSomething at this location */}
};
final adds an explicit intent to not have your function overridden, and will cause a compiler error should this be violated:
struct A {
virtual int foo(); // #1
};
struct B : A {
int foo();
};
As the code stands, it compiles, and B::foo overrides A::foo. B::foo is also virtual, by the way. However, if we change #1 to virtual int foo() final, then this is a compiler error, and we are not allowed to override A::foo any further in derived classes.
Note that this does not allow us to "reopen" a new hierarchy, i.e. there's no way to make B::foo a new, unrelated function that can be independently at the head of a new virtual hierarchy. Once a function is final, it can never be declared again in any derived class.
The final keyword allows you to declare a virtual method, override it N times, and then mandate that 'this can no longer be overridden'. It would be useful in restricting use of your derived class, so that you can say "I know my super class lets you override this, but if you want to derive from me, you can't!".
struct Foo
{
virtual void DoStuff();
}
struct Bar : public Foo
{
void DoStuff() final;
}
struct Babar : public Bar
{
void DoStuff(); // error!
}
As other posters pointed out, it cannot be applied to non-virtual functions.
One purpose of the final keyword is to prevent accidental overriding of a method. In my example, DoStuff() may have been a helper function that the derived class simply needs to rename to get correct behavior. Without final, the error would not be discovered until testing.
Final keyword in C++ when added to a function, prevents it from being overridden by derived classes.
Also when added to a class prevents inheritance of any type.
Consider the following example which shows use of final specifier. This program fails in compilation.
#include <iostream>
using namespace std;
class Base
{
public:
virtual void myfun() final
{
cout << "myfun() in Base";
}
};
class Derived : public Base
{
void myfun()
{
cout << "myfun() in Derived\n";
}
};
int main()
{
Derived d;
Base &b = d;
b.myfun();
return 0;
}
Also:
#include <iostream>
class Base final
{
};
class Derived : public Base
{
};
int main()
{
Derived d;
return 0;
}
Final keyword have the following purposes in C++
If you make a virtual method in base class as final, it cannot be overridden in the derived class. It will show a compilation error:
class Base {
public:
virtual void display() final {
cout << "from base" << endl;
}
};
class Child : public Base {
public:
void display() {
cout << "from child" << endl;
}
};
int main() {
Base *b = new Child();
b->display();
cin.get();
return 0;
}
If we make a class as final, it cannot be inherited by its child classes:
class Base final {
public:
void displayBase() {
cout << "from base" << endl;
}
};
class Child :public Base {
public:
void displayChild() {
cout << "from child" << endl;
}
};
Note: the main difference with final keyword in Java is ,
a) final is not actually a keyword in C++.
you can have a variable named as final in C++
b) In Java, final keyword is always added before the class keyword.
Supplement to Mario Knezović 's answer:
class IA
{
public:
virtual int getNum() const = 0;
};
class BaseA : public IA
{
public:
inline virtual int getNum() const final {return ...};
};
class ImplA : public BaseA {...};
IA* pa = ...;
...
ImplA* impla = static_cast<ImplA*>(pa);
//the following line should cause compiler to use the inlined function BaseA::getNum(),
//instead of dynamic binding (via vtable or something).
//any class/subclass of BaseA will benefit from it
int n = impla->getNum();
The above code shows the theory, but not actually tested on real compilers. Much appreciated if anyone paste a disassembled output.
The following code:
struct interface_base
{
virtual void foo() = 0;
};
struct interface : public interface_base
{
virtual void bar() = 0;
};
struct implementation_base : public interface_base
{
void foo();
};
struct implementation : public implementation_base, public interface
{
void bar();
};
int main()
{
implementation x;
}
fails to compile with the following errors:
test.cpp: In function 'int main()':
test.cpp:23:20: error: cannot declare variable 'x' to be of abstract type 'implementation'
test.cpp:16:8: note: because the following virtual functions are pure within 'implementation':
test.cpp:3:18: note: virtual void interface_base::foo()
I have played around with it and figured out that making the 'interface -> interface_base' and 'implementation_base -> interface_base' inheritances virtual, fixes the problem, but I don't understand why. Can someone please explain what is going on?
p.s. I omitted the virtual destructors on purpose to make the code shorter. Please don't tell me to put them in, I already know :)
You have two interface_base base classes in your inheritance tree. This means you must provide two implementations of foo(). And calling either of them will be really awkward, requiring multiple casts to disambiguate. This usually is not what you want.
To resolve this, use virtual inheritance:
struct interface_base
{
virtual void foo() = 0;
};
struct interface : virtual public interface_base
{
virtual void bar() = 0;
};
struct implementation_base : virtual public interface_base
{
void foo();
};
struct implementation : public implementation_base, virtual public interface
{
void bar();
};
int main()
{
implementation x;
}
With virtual inheritance, only one instance of the base class in question is created in the inheritance heirarchy for all virtual mentions. Thus, there's only one foo(), which can be satisfied by implementation_base::foo().
For more information, see this prior question - the answers provide some nice diagrams to make this all more clear.
The usual C++ idiom is:
public virtual inheritance for interface classes
private non-virtual inheritance for implementation classes
In this case we would have:
struct interface_base
{
virtual void foo() = 0;
};
struct interface : virtual public interface_base
{
virtual void bar() = 0;
};
struct implementation_base : virtual public interface_base
{
void foo();
};
struct implementation : private implementation_base,
virtual public interface
{
void bar();
};
In implementation, the unique interface_base virtual base is :
publicly inherited via interface: implementation --public--> interface --public--> interface_base
privately inherited via implementation_base: implementation --private--> implementation_base --public--> interface_base
When client code does one of these derived to base conversions:
derived to base pointer conversions,
reference binding of base type with an initializer of static type derived,
access to inherited base class members via a lvalue of derived static type,
what matters is only that there is a least one accessible inheritance path from the derived class to the given base class subobject; other inaccessible paths are simply ignored. Because inheritance of the base class is only virtual here, there is only one base class subject so these conversions are never ambiguous.
Here, the conversion from implementation to interface_base, can always be done by client code via interface; the other inaccessible path does not matter at all. The unique interface_base virtual base is publicly inherited from implementation.
In many cases, the implementation classes (implementation, implementation_base) will be kept hidden from client code: only pointers or references to the interface classes (interface, interface_base) will be exposed.
For the case of 'solving' the diamond inheritance problem, the solutions offered by bdonlan are valid. Having said that, you can avoid the diamond-problem with design. Why must every instance of a given class be seen as both classes? Are you ever going to pass this same object to a class that says something like:
void ConsumeFood(Food *food);
void ConsumeDrink(Drink *drink);
class NutritionalConsumable {
float calories() = 0;
float GetNutritionalValue(NUTRITION_ID nutrition) = 0;
};
class Drink : public NutritionalConsumable {
void Sip() = 0;
};
class Food : public NutritionalConsumable {
void Chew() = 0;
};
class Icecream : public Drink, virtual public Food {};
void ConsumeNutrition(NutritionalConsumable *consumable) {
ConsumeFood(dynamic_cast<Food*>(food));
ConsumeDrink(dynamic_cast<Drink*>(drink));
}
// Or moreso
void ConsumeIcecream(Icecream *icecream) {
ConsumeDrink(icecream);
ConsumeFood(icecream);
}
Surely it would be better in this case for Icecream to just implement NutritionalConsumable and provide a GetAsDrink() and GetAsFood() method that will return a proxy, purely for the sake of appearing as either food or drink. Otherwise that suggests that there is a method or object that accepts a Food but somehow wants to later see it as a Drink, which can only be achieved with a dynamic_cast, and needn't be the case with a more appropriate design.