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.
Related
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 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.
In C++ why the pure virtual method mandates its compulsory overriding only to its immediate children (for object creation), but not to the grand children and so on ?
struct B {
virtual void foo () = 0;
};
struct D : B {
virtual void foo () { ... };
};
struct DD : D {
// ok! ... if 'B::foo' is not overridden; it will use 'D::foo' implicitly
};
I don't see any big deal in leaving this feature out.
For example, at language design point of view, it could have been possible that, struct DD is allowed to use D::foo only if it has some explicit statement like using D::foo;. Otherwise it has to override foo compulsory.
Is there any practical way of having this effect in C++?
I found one mechanism, where at least we are prompted to announce the overridden method explicitly. It's not the perfect way though.
Suppose, we have few pure virtual methods in the base class B:
class B {
virtual void foo () = 0;
virtual void bar (int) = 0;
};
Among them, suppose we want only foo() to be overridden by the whole hierarchy. For simplicity, we have to have a virtual base class, which contains that particular method. It has a template constructor, which just accepts the type same as that method.
class Register_foo {
virtual void foo () = 0; // declare here
template<typename T> // this matches the signature of 'foo'
Register_foo (void (T::*)()) {}
};
class B : public virtual Register_foo { // <---- virtual inheritance
virtual void bar (int) = 0;
Base () : Register_foo(&Base::foo) {} // <--- explicitly pass the function name
};
Every subsequent child class in the hierarchy would have to register a foo inside its every constructor explicitly. e.g.:
struct D : B {
D () : Register_foo(&D::foo) {}
virtual void foo () {};
};
This registration mechanism has nothing to do with the business logic. Though, the child class can choose to register using its own foo or its parent's foo or even some similar syntax method, but at least that is announced explicitly.
In your example, you have not declared D::foo pure; that is why it does not need to be overridden. If you want to require that it be overridden again, then declare it pure.
If you want to be able to instantiate D, but force any further derived classes to override foo, then you can't. However, you could derive yet another class from D that redeclares it pure, and then classes derived from that must override it again.
What you're basically asking for is to require that the most derived
class implement the functiom. And my question is: why? About the only
time I can imagine this to be relevant is a function like clone() or
another(), which returns a new instance of the same type. And that's
what you really want to enforce, that the new instance has the same
type; even there, where the function is actually implemented is
irrelevant. And you can enforce that:
class Base
{
virtual Base* doClone() const = 0;
public:
Base* clone() const
{
Base* results = doClone();
assert( typeid(*results) == typeid(*this) );
return results;
}
}
(In practice, I've never found people forgetting to override clone to
be a real problem, so I've never bothered with something like the above.
It's a generally useful technique, however, anytime you want to enforce
post-conditions.)
A pure virtual means that to be instantiated, the pure virtual must be overridden in some descendant of the class that declares the pure virtual function. That can be in the class being instantiated or any intermediate class between the base that declares the pure virtual, and the one being instantiated.
It's still possible, however, to have intermediate classes that derive from one with a pure virtual without overriding that pure virtual. Like the class that declares the pure virtual, those classes can only be used as based classes; you can't create instances of those classes, only of classes that derive from them, in which every pure virtual has been implemented.
As far as requiring that a descendant override a virtual, even if an intermediate class has already done so, the answer is no, C++ doesn't provide anything that's at least intended to do that. It almost seems like you might be able to hack something together using multiple (probably virtual) inheritance so the implementation in the intermediate class would be present but attempting to use it would be ambiguous, but I haven't thought that through enough to be sure how (or if) it would work -- and even if it did, it would only do its trick when trying to call the function in question, not just instantiate an object.
Is there any practical way of having this effect in C++?
No, and for good reason. Imagine maintenance in a large project if this were part of the standard. Some base class or intermediate base class needs to add some public interface, an abstract interface. Now, every single child and grandchild thereof would need to changed and recompiled (even if it were as simple as adding using D::foo() as you suggested), you probably see where this is heading, hells kitchen.
If you really want to enforce implementation you can force implementation of some other pure virtual in the child class(s). This can also be done using the CRTP pattern as well.
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.