I have an abstract class IExecutable
class IExecutable
{
public:
virtual ActionStatus Execute() = 0;
};
With an intermediate class Action
class Action : public IExecutable
{
virtual ActionStatus Execute();
};
which implements Execute(), and other final classes, such as GoTo
class GoTo : public Action
{
...
};
GoTo does not implement Execute(). The compiler sees GoTo as an abstract class because it doesn't implement Execute().
Two questions:
Isn't the fact that Action implements Execute() enough so that GoTo shouldn't need to implement it?
And if not, how would that be fixed? It doesn't make sense to have to reimplement Execute() for every final class when it's the same for all final Actions.
It sounds like this isn't the whole story. GoTo will be abstract if there is any pure virtual function without implementation somewhere up the hierarchy.
In C++11, you can ensure that Execute is properly implemented using the override keyword:
virtual ActionStatus Execute() override;
This will cause a specific diagnostic if you accidentally declare a new virtual function instead of an override.
You can specify that GoTo is not the base of anything using final, which may cause the compiler to complain if it is abstract (but this may not be required):
class GoTo final : public Action
In any case, the compiler should tell you what function was not implemented to help you track down this kind of bug.
Related
Let's imagine I have the following code:
class Base {
virtual void myFunc();
};
class Subclass1 : public Base { // OK
virtual void myFunc() override; // overrides the base function
};
class Subclass2 : public Base { // How to make this fail ?
// does not declare an override for myFunc
};
Is there any way in C++ to make compilation fail because Subclass2 does not implement its variant of myFunc() ? I know how to make the opposite, that is to make compilation fail because Subclass1 overrides myFunc() (by using final), but I'm not aware of any mechanic to achieve what I want in C++11.
I'm curious about possibilities in later C++ standards as well.
You can force one subclass level to override a method, by making it 'pure' (virtual method()=0;), but you cannot force multiple levels to each override it again - and that should really not be your concern.
In other words, if you provide a base (or derived) class to an enduser, you can force him to override (define) a method in his derived class. If that user wants to derive from his derived class again, it’s his business to decide if the next (further) derived class needs a different override or not.
Let us suppose that we have an abstract class NonEditableSuperBase from which we create another abstract class MyBase.
The first class NonEditableSuperBase has a virtual function (non pure virtual). However, I want to force that if someone creates a class that derives from MyBase, he/she must provide an implementation to the mentioned function.
Hence, my idea is to define the function as pure virtual in MyBase.
My question: Is it a bad idea given that it was just virtual in NonEditableSuperBase?
Example:
//NonEditableSuperBase.h
class NonEditableSuperBase
{
...
public:
virtual int someMethod(); //It has an implementation, suppose {return 42;}
};
//MyBase.h
class MyBase: public NonEditableSuperBase
{
public:
explicit MyBase();
virtual ~MyBase() = default;
virtual int someMethod() = 0; //I make it pure virtual
};
//MyBase.cpp
MyBase::MyBase() : NonEditableSuperBase() { }
//Now someone creates a derived class from MyBase.
class SuperDerived : public MyBase
{
public:
explicit SuperDerived();
int someMethod(); //The user must create an implementation of the function
};
Update:
As an example, in my case I want to create some derived classes from the QAbstractTableModel class of the Qt framework. To reuse some code I want to create an intermediate abstract class.
QAbstractTableModel <- MyAbstractModel <- MyModelA (or MyModelB ... etc).
However, I want to ensure that the models (MyModelA, MyModelB) re-implement some of the virtual functions of QAbstractTableModel (like the ::index() function) because some of the additional methods of MyAbstractModel requires specific implementations of the primer functions.
From ISO IEC 14882 2014:
§ 10.4 says:
5 [ Note: An abstract class can be derived from a class that is not abstract, and a pure virtual function may
override a virtual function which is not pure. —end note ]
So It's perfectly possible to do that.
Example of use case:
You can have a basic type, that is implemented as a concrete type (base class). Now, for subtypes, we might be in a need of further additional information. So, we can have an abstract intermediate object to meet our needs.
[I'm assuming that the intent was for MyBase to publicly derive from NonEditableSuperBase, which is not what the code sample in the question actually does.]
It doesn't seem inherently dangerous, but consider that a class like SuperDerived that derives from MyBase could explicitly choose to use the NonEditableSuperBase implementation.
class SuperDerived : public MyBase {
public:
using NonEditableSuperBase::someMethod;
// Or, explicitly:
// int someMethod() override { return NonEditableSuperBase::someMethod(); }
};
This satisfies the pure-virtual requirement imposed by MyBase but acts exactly as if MyBase didn't have that requirement. You've made the author of SuperDerived do something, but you haven't actually prevented them from using the ultimate base class's implementation.
I have following dilemma:
I have a full abstract class. Each inheriting class will need 3 same parameters. Each of them will additionally need other specific parameters.
I could:
1) implement a common constructor for initializing 3 common parameters in my base class, but then I have to make non-abstract getters for corresponding fields (they are private).
OR
2) leave my base class abstract and implement constructors in inherited classes, but then I have to make it in each class fields for common parameters.
Which is a better approach? I don't want to use protected members.
An abstract class is one who has at least one pure virtual (or, as you call it, abstract) function. Having non-abstract, non-virtual functions does not change the fact that your class is abstract as long as it has at least one pure virtual function. Go for having the common functionality in your base class, even if it is abstract.
One way to avoid code duplication without polluting your abstract interface with data members, is by introducing an additional level of inheritance:
// Only pure virtual functions here
class Interface {
public:
virtual void foo() = 0;
};
// Things shared between implementations
class AbstractBase : public Interface {
};
class ImplementationA : public AbstractBase {
};
class ImplementationB : public AbstractBase {
};
If your class looks like this, a pure abstract class:
class IFoo {
public:
virtual void doThings() = 0;
}
class Foo {
public:
Foo(std::string str);
void doThings() override;
}
The value your inheritance has is to provide you with the oppurtunity to subsitute Foo with another at runtime, but hiding concrete implementations behind interfaces. You can't use that advantage with Constructors, there's no such thing as a virtual constructor (that's why things like the Abstract Factory Pattern exist). All your implementations of Foo take a std::string and all your implementations of doThings use that string? Great, but that's a coincidence not a contract and doesn't belong in IFoo.
Lets talk about if you've created concrete implementations in IFoo, so that it's a abstract class and not a pure abstract class (IFoo would be a bad name now btw). (*1) Lets assume using inheritance to share behaviour was the correct choice for you class, which is sometimes true. If the class has fields that need to be initialised create a protected constructor (to be called from every child implementation) and remove/ommit the default one.
class BaseFoo {
private:
std::string _fooo;
protected:
BaseFoo(std::string fooo) : _fooo(fooo) {}
public:
virtual void doThings() = 0;
std::string whatsTheBaseString() { return _fooo;}
}
Above is the way you correctly pass fields needed by a base class from the child constructor. This is a compile time guarantee that a child class will 'remember' to initialize _fooo correctly and avoids exposing the actual member fooo to child classes. Trying to initialize _fooo in all the child constructors directly would be incorrect here.
*1) Quickly, why? Composition may be a better tool here?.
I'm using class to declare interface. I just want to define method signature. This method must be implemented in any non-abstract subclass. I don't need method to be virtual. This is default behaviour in C# BTW (i came from C#/Java world)
However it seems in C++ it is not possible. I either declare method in regular way
void Foo::Method()
and then it is not mandatory to implement it or declare method as "pure virtual"
void virtual Foo::Method() = 0;
and then method become virtual, but I want to avoid this to save performance a little bit.
It seems I want to have something like that
void Foo::Method() = 0;
but that would be compilation error
if you're planning on using the derived class from template code, i.e. compile time polymorphism, then you only need to document the expected signature
the code using a derived class simply won't compile and link if the used function isn't implemented
otherwise, for runtime polymorphism it needs to be virtual, or else it won't be called
I believe that you might be confused with regard to how C# version works:
class A {
public void NonVirt() { Console.Out.WriteLine("A:NonVirt"); }
public virtual void Virt() { Console.Out.WriteLine("A:Virt"); }
}
class B : A {
public void NonVirt() { Console.Out.WriteLine("B:NonVirt"); }
public override void Virt() { Console.Out.WriteLine("B:Virt"); }
}
class Program {
static void Main(string[] args) {
A x = new B();
x.NonVirt();
x.Virt();
}
}
This will output
A:NonVirt
B:Virt
So even in C#, you need to make method virtual if you want to call the derived implementation.
If method must be implemented in all non-abstract subclasses this means that you need to call them through base class pointer. This in turn means that you need to make them virtual, same as in C# (and likely in Java, but I am not sure)
Btw, price of virtual call is a few nanoseconds on modern CPUs, so I am not sure if it is worth it but lets say that it is.
If you want to avoid the cost of virtual call, you should use compile time polymorphism via templates
There is no notion of interface in C++. The only way to achieve your goal is to create a base class defining as virtual and = 0 all the methods which must be actually defined in subclasses.
class IBase {
// ...
virtual void f1() = 0;
// ....
}
That class will be virtual pure if all methods are defined like f1, which is the closest to an interface you can get.
The concept of interface in Java is a bit like a contract with regard to classes implementing it. The compiler enforces the constraints of the contract by checking the content of the implementors. This notion of contract or explicit structural subtyping does not exist formally in C++.
However, you can manually verify that such constraints are respected by defining a template wich will expect as a parameter a class with the defined methods or attributes, and using that template on the classes to be verified. This could be considered a form of unit testing I suppose.
Sometimes I accidentally forget to call the superclass's method in C++ when I override a method.
Is there any way to help figure out when I'm overriding a method with, so that I don't forget to call the superclass's method? (Something like Java's #Override, except that C++ doesn't have annotations...)
One suggestion is the Non-Virtual Inferface Idiom. I.e., make your public methods non-virtual and have them call private or protected virtual methods that derived classes can override to implement their specific behavior.
If you don't have control over the base class, you could perhaps use an intermediate class:
class Foo // Don't control this one
{
public:
virtual void action();
};
class Bar : public Foo // Intermediate base class
{
public:
virtual void action()
{
doAction();
Foo::action();
}
protected:
virtual void doAction() = 0;
};
Derive your classes from Bar and override doAction() on each. You could even have doBeforeAction() and doAfterAction() if necessary.
With regards to Java's #Override, there is a direct equivalent in C++11, namely the override special identifier.
Sadly, neither #Override nor override solve the problem since: (a) they're optional; (b) the responsibility of calling the base class's method still rests with the programmer.
Furthermore, I don't know of any widely available method that would address the problem (it's quite tricky, esp. given that you don't necessarily want to call the base class's method -- how is the machine to know?).
Unfortunately Í'm not aware of a common mechanism to do this.
In C++ if you're needing to use the base class's functionality in addition to added child functionality you should look at the template method pattern. This way the common logic always lives in the base class and there's no way to forget to execute it, and you override in the child only the piece you need to change.