Eclipse reports bug on valid cpp inheritance - c++

Eclipse is reporting a bug on "new Listener()", though this compiles and executes with g++. Note the classes have more data than listed here as this is trimmed down, so removing the seemingly empty classes is not an option. Is there something that I can add/change to make both Eclipse and g++ happy. I will not be able to change the Base* classes though.
class BaseIntf {
public:
virtual ~BaseIntf() {}
virtual void foo() = 0;
};
class BaseImpl: public virtual BaseIntf {
public:
virtual void foo() {}
};
class ListenerBaseInft: public virtual BaseIntf {
};
class Listener: public ListenerBaseInft, public BaseImpl {
};
int main(int argc, char *argv[]) {
// Eclipse:
// The type 'Listener' must implement the inherited pure virtual method 'BaseIntf::foo'
Listener* listener = new Listener();
listener->foo();
return 0;
}

C++ has a feature called dominance. Normally, when a class (say A) is derived from two classes (say A1 and A2), each implementing the same virtual function (say void f()), the derived class needs to implement that function as well. A pure virtual function counts as an implementation too.
However, there is an exception: when A1 is itself derived from A2, then A1s implementation of f() is said to dominate that of A2, and the latter is excluded from consideration. Thus, A does not have to reimplement f().
Your compiler probably fails to take that exception into account. It's a compiler bug.
To work around it, define foo in Listener:
void foo() { BaseImpl::foo(); }
which is ugly, but so is the compiler bug.

Related

Merging abstract and final methods through multiple inheritance

Consider the following program:
#include <stdio.h>
#include <memory>
using namespace std;
class WheeledVehicle {
public:
virtual void drive() const { printf("Default driving implementation."); }
};
class GroundVehicle : public WheeledVehicle {
public:
void drive() const final { WheeledVehicle::drive(); }
};
class DrivableAssaultMachine {
public:
virtual void drive() const = 0;
void fire_cannon();
};
class FighterJet : public DrivableAssaultMachine {
public:
void fly() const { printf("flying my plane.\n"); }
void drive() const override { fly(); }
};
class Tank : public DrivableAssaultMachine, public GroundVehicle {
};
int main(int argc, char **argv) {
make_shared<Tank>()->drive();
return EXIT_SUCCESS;
}
I would like to make this program compile using only modifications to Tank. If I implement drive, then it contradicts the final declaration in GroundVehicle. If I don't implement it, then Tank is abstract and can't be instantiated. Is there some other way to get Tank's inherited implementation of drive() be recognized in the context of inheriting from DrivableAssaultMachine?
EDIT: Renamed everything to provide a more concrete example.
Conceptual flaw:
class FighterJet could not be derived from DrivableAssaultMachine as
DrivableAssaultMachine is derived from class GroundVehicle.
FighterJet are not GroundVehicles.
You should differentiate GroundVehicles and AirVehicles and add: drive and fly as member functions in those and then derive Tank from the first and FighterJet, from the second.
After the n-th Edit:
You've just took under consideration what I've told you and changed the inheritance structure, braking DrivableAssaultMachine from WheeledVehicle
Final Answers:
If I implement drive(), then it contradicts the final declaration in GroundVehicle.
drive() is redundant in FighterJet(as it has fly() available), removing it from there will allow you to override it in Tank.
The virtual drive in DrivableAssaultMachine has nothing to do with the drive() inherited from WheeledVehicle. So there should be ambiguity when try to override it in Tank, as it has as base classes both DrivableAssaultMachine and indirectly WheeledVehicle.
Note: In general your abstract class should provide basic functionality, for example member function: a virtual move() and then the derived classes should wrap it up(override it) and specialize it to their needs, for example: drive() and fly(). Your only tools to specify visibility and accessibility is via the public, private and protected specifier during the definition and the inheritance.
I solved this by creating a diamond hierarchy and using virtual inheritance. Here is a simplified visualization of my hierarchy from the question:
WheeledVehicle
\
DrivableAssaultMachine GroundVehicle
\ /
Tank
Although my feeling is that the compiler should be able to resolve ambiguities and virtualization here, the fact is that it can't. My solution is to fully connect the diamond and use virtual inheritance:
Drivable
/ \
/ WheeledVehicle
/ /
DrivableAssaultMachine GroundVehicle
\ /
Tank
Here is the final program:
#include <stdio.h>
#include <memory>
using namespace std;
class Drivable {
public:
virtual void drive() const = 0;
};
class WheeledVehicle : public virtual Drivable {
public:
virtual void drive() const override { printf("Default driving implementation.\n"); }
};
class GroundVehicle : public WheeledVehicle {
public:
void drive() const final { WheeledVehicle::drive(); }
};
class DrivableAssaultMachine : public virtual Drivable {
public:
void fire_cannon();
};
class Tank : public DrivableAssaultMachine, public GroundVehicle {
};
int main(int argc, char **argv) {
make_shared<Tank>()->drive();
return EXIT_SUCCESS;
}
In general, the workaround appears to be using simple virtual interfaces near the root of your inheritance tree, and combining or complexifying interfaces as you get toward the leaves.
C++ is not Java.
The inheritance and overriding in C++ has to be more explicit than in Java. (I think C++ is right here.)
In C++, two virtual functions declarations foo (with the same signature) are considered homonyms, distinct, unrelated functions unless one declaration overrides the other.
struct B1 {
virtual void foo();
};
struct B2 {
virtual void foo();
};
struct D : B1, B2 {
void bar();
};
D has two inherited declarations of a member function with the same signature, and unqualified calls to foo() within D::bar() would be ambiguous, but the definition of class D is well formed. There is no problem with having potential ambiguities in C++, only ambiguous calls are disallowed.
This means that you can derive from base classes with unrelated homonyms. You just have to avoid ambiguous calls.
Even when both declarations of foo() come from the same class:
struct B {
virtual void foo();
};
struct Left : B {
};
struct Right : B {
};
struct D : Left, Right {
void bar();
};
Both inherited declarations of B::foo() are simply homonyms: they come from the same class, but they in two distinct base classes. C++ lets you have homonyms. The compiler doesn't believe the functions do the same thing or are related in any way other than having the same name, explicit argument list (the arguments inside parentheses), implicit this argument type (of type Base*), and being declared by the same declaration in the source file!
Of course, there is potential ambiguity: if you try to call foo on a derived object, or try to convert (implicitly, or explicitly with static_cast or a C-style cast) a derived pointer to an ambiguous base class pointer.
[Note: some people call that "diamond inheritance" (although the inheritance graph is a tree not a "diamond"), or "dreaded diamond" (it's only dreaded if you don't understand MI in C++) or "diamond of death" (who died?) or "diamond of end of the world" (now I'm making stuff up, but it's only slightly more over the top than "diamond of death"). Seriously, don't freak out people with a potential ambiguity. --end note]
This means that you can derive from base classes with unrelated derivation of the same non virtual base class. You just have to avoid ambiguous calls and ambiguous conversions. (This can happen when two classes derive from the same utility class like refcounted_base.)
In Java, multiple inheritance of classes doesn't exist, but multiple interface inheritance does, and distinct declarations of a given (pure virtual) function are synonyms:
interface I {
void foo();
}
class Base {
public void foo() { }
}
class Der extends Base implements I {
}
Here Base::foo() will implement I::foo() even if neither Base nor I names or knows about one another. This never happens in C++.
Although my feeling is that the compiler should be able to resolve ambiguities and virtualization here,
Your feeling is based on an incorrect notion of C++ inheritance model; the compiler cannot know your intent. You gave the compiler two different declarations, just because they are homonyms does not mean you intended to have synonyms.
By inheriting from a common interface (with virtual inheritance as you should with interfaces), you are telling the compiler that there is only one feature drive. All uses of drive are synonyms now.

Design Techniques to Defend Against the Pitfalls of Inheritance in C++

Summary
I relied on the compiler to point to every location in my code I would need to update while changing the signature of a member function in a parent class, but the compiler failed to point out an overridden instance of that function in a child class, causing a logical error in my program. I would like to re-implement the classes so that I can rely more on the compiler while making changes of this kind.
Details via an example
I have the following classes:
class A
{
public:
void foo();
virtual void bar();
}
class B: public A
{
public:
void bar();
}
This is the implementation:
void A:foo(){ ... bar(); ... }
void A:bar(){ ... }
void B:bar(){ ... }
Note that whhen I call b->foo() (where b has type B* and B is a subclass of A) the bar() method called is B:bar()
After changing the type-signature of A:bar(), to say A:bar(some_parameter), my code looked like this:
void A:foo(){ ... bar(param); ... }
void A:bar(param) { ... }
void B:bar(){ ... }
Now, when I call b->foo(), of course A:bar(param) is called. I expected such a case to be caught by the compiler, but I realize now that it cannot.
How would I implement classes A & B to avoid bugs of this class.
I expected such a case to be caught by the compiler, but I realize now
that it cannot do so.
Actually, it can do so. You can use override on B::bar's declaration, and the compiler will error if there is no suitable base class function for it to override.
The way to detect this issue in c++03 where it did not have yet the override specifier (It is since c++11 standard) is to do pure virtual method in an interface. If you change the sign of a pure virtual method, all its subclasses must change it too or they will not compile.
Do not depend on concrete classes. Depend on interfaces. You will do better designs.
Your design would change to something like this:
class IA
{
public:
void foo() { ... bar(); ...}
virtual void bar() = 0;
virtual ~IA() {}
};
class A : public IA
{
public:
void bar() {...}
};
class B : public IA
{
public:
void bar() {...}
};
Now, if you change the sign of bar in the interface, all its subclasses must change it too.

What is the purpose of the "final" keyword in C++11 for functions?

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.

override c++ virtual method

I have a class template where some methods are defined as virtual to give the ability for the user of my class to give an implementation for them in his derived class. Note that in my template class there is some non-virtual methods that makes use of the virtual one (a virtual class that should return a value is called in a non-virtual class).
Can you give me a simple example of a correct code where the virtual method of the parent class should return a value (but it's implementation is provided in a child class) and the value returned by the virtual method in the parent class is used in other methods of that class. Because I saw somewhere (for example here: Safely override C++ virtual functions) that this can cause some problems and the user defined method will note override the virtual method of the parent class.
Note: I program with Code::Blocks using g++ compiler.
EDIT: as requested here a simple example of what I want:
template<typename T>
class parent {
public:
// Public methods that user can call
int getSomething(T t);
void putSomething(T t, int x);
// public method that user should implement in his code
virtual float compute(T t) { }
// protected or private methods and attributes used internally by putSomething ...
float doComplexeThings(...); // this can call
};
The method compute() should be implemented by the user (the child class). However, this method compute() is called by putSomething() and doComplexeThings() for example.
If you can use C++11 features in your compiler then overrides can be tagged as so with the override special identifier:
float compute() override;
The above line in a derived class will cause a compiler error as the function does not override a member function in the base (incorrect signature, missing argument). But note that this must be done in each derived class, it is not a solution that you can impose from the base class.
From the base class you can only force the override by making the function pure virtual, but that changes the semantics. It does not avoid problems while overriding, but rather forces overriding in all cases. I would avoid this approach, and if you are to follow it and there is a sensible implementation for the base type, make the function virtual and provide a definition so that your derived classes's implementation can just call the functions the base type (i.e. you force the implementation, but in the simplest cases it will just forward the call to the parent)
You just have to make sure that the methods have the same signature (including const/mutable modifiers and argument types). You can use a pure virtual definition to provoke compiler errors if you fail to override the function in a subclass.
class parent {
public:
// pure virtual method must be provided in subclass
virtual void handle_event(int something) = 0;
};
class child : public parent {
public:
virtual void handle_event(int something) {
// new exciting code
}
};
class incomplete_child : public parent {
public:
virtual void handle_event(int something) const {
// does not override the pure virtual method
}
};
int main() {
parent *p = new child();
p->handle_event(1); // will call child::handle_event
parent *p = new incomplete_child(); // will not compile because handle_event
// was not correctly overridden
}
This question is asked in 2013. It's pretty old but I found something new which doesn't exist in the answers.
We need to understanding three concept is overload, overwrite, and hide.
Short answer, you want to overload the inheritance function from base class.
However, overload is the mechanism to add multiple behavior for function which needs all these functions under the same scale. But the virtual function is in the Base class obviously.
class A {
public:
virtual void print() {
cout << id_ << std::endl;
}
private:
string id_ = "A";
};
class B : A {
public:
using A::print;
void print(string id) {
std::cout << id << std::endl;
}
};
int main(int argc, char const *argv[]) {
/* code */
A a;
a.print();
B b;
b.print();
b.print("B");
return 0;
}
Add using A::print; in your derive class will do the work!
Though I don't feel it's a good idea since the philosophy behind the overload and inheritance is different, it may not a good idea to nest them together.

What exactly does runtime polymorphism mean?

I'm slightly confused about runtime polymorphism. Correct me if I am wrong, but to my knowledge, runtime polymorphism means that function definitions will get resolved at runtime.
Take this example:
class a
{
a();
~a();
void baseclass();
}
class b: class a
{
b();
~b();
void derivedclass1();
}
class c: class a
{
c();
~c();
void derivedclass2();
}
Calling methodology:
b derived1;
a *baseptr = &derived1; //here base pointer knows that i'm pointing to derived class b.
baseptr->derivedclass1();
In the above calling methodology, the base class knows that it's pointing to derived class b.
So where does the ambiguity exist?
In what cases will the function definitions get resolved at runtime?
This code, at run time, calls the correct version of f() depending on the type of object (A or B) that was actually created - no "ambiguity". The type cannot be known at compile-time, because it is selected randomly at run-time.
struct A {
virtual ~A() {}
virtual void f() {}
};
struct B : public A {
virtual void f() {}
};
int main() {
A * a = 0;
if ( rand() % 2 ) {
a = new A;
}
else {
a = new B;
}
a->f(); // calls correct f()
delete a;
}
There is no ambiguity exists in the example provided.
If the base class has the same function name as the derived class, and if you call in the way you specified, it will call the base class's function instead of the derived class one.
In such cases, you can use the virtual keyword, to ensure that the function gets called from the object that it is currently being pointed. It is resolved during the run time.
Here you can find more explanation..
Turn this
void baseclass();
to
virtual void baseclass();
Override this in your Derived classes b and c. Then
b *derived1 = new derived1 ();
a *baseptr = derived1; //base pointer pointing to derived class b.
baseptr->baseclass();
will invoke derived1 definition, expressing run time polymorphism. And do remember about making your destructor virtual in Base. Some basic reading material for polymorphism
Runtime means that exact method will be known only at run time. Consider this example:
class BaseClass
{
public:
virtual void method() {...};
};
class DerivedClassA : public BaseClass
{
virtual void method() {...};
};
class DerivedClassB : public BaseClass
{
virtual void method() {...};
};
void func(BaseClass* a)
{
a->method();
}
When you implement your ::func() you don't know exactly type of instance pointed by BaseClass* a. It might be DerivedClassA or DerivedClassB instance etc.
You should realize, that runtime polymorphism requires special support from language (and maybe some overhead for calling "virtual" functions). In C++ you "request" for dynamic polymorphism by declaring methods of base class "virtual" and using public inheritance.
You need to have some useful business method declared in the base and in each derived class. Then you have code such as
a->someMethod();
Now the a pointer might point to an instance of any of the derived classes, and so the type of what a is pointing to must determine which someMethod() is called.
Lets have an experiment
#include <iostream>
using namespace std;
class aBaseClass
{
public:
void testFunction(){cout<<"hello base";}///Not declared as virtual!!!!
};
class aDerivedClass:public aBaseClass
{
public:
void testFunction(){cout<<"hello derived one";}
};
class anotherDerivedClass:public aDerivedClass
{
public:
void testFunction(){cout<<"hello derived two";}
};
int main()
{
aBaseClass *aBaseClassPointer;
aBaseClassPointer=new aDerivedClass;
aBaseClassPointer->testFunction();
}
The above code does not support run time polymorphism. Lets run and analyze it.
The output is
hello base
Just change the line void testFunction(){cout<<"hello base";} to virtual void testFunction(){cout<<"hello base";} in aBaseClass. Run and analyze it. We see that runtime polymorphism is achieved. The calling of appropriate function is determined at run time.
Again change the line aBaseClassPointer=new aDerivedClass to aBaseClassPointer=new anotherDerivedClass in main function and see the output. Thus the appropriate function calling is determined at run time (when the program is running).