Implementing pure virtual functions with multiple inheritance - c++

Suppose there is this interface:
class A{
public:
virtual foo()=0;
};
And a class B which implements this interface:
class B:public A{
public:
virtual foo(){} //Foo implemented by B
}
Finally, a class C which has classes A and B as base classes:
Class C : public A, public B {
};
My question is, there is a way to tell the compiler that the implementation for foo is the one from class B without doing an explicit call to B::foo()?

As #BenVoigt pointed out in the comments, the below answer only works due to a bug in g++ (meaning it isn't guaranteed to keep working, and it definitely isn't portable). Thus, although it may do what you want if you use a particular (buggy) compiler, it isn't an option you should use.
Do use virtual inheritance though.
This isn't exactly the scenario that the code in the question implies, but the sentence
My question is, there is a way to tell the compiler that the
implementation for foo is the one from class B without doing an
explicit call to B::foo()?
seems to be asking for syntax to distinguish between multiple base versions of a function without using the :: qualifier.
You can do this with the using directive:
#include <iostream>
class A {
public:
A(){}
virtual void foo(){std::cout<<"A func";}
};
class B: virtual public A {
public:
B(){}
virtual void foo(){std::cout<<"B func";}
};
class C:virtual public A, virtual public B {
public:
C(){}
using A::foo; // tells the compiler which version to use
// could also say using B::foo, though this is unnecessary
};
int main() {
C c;
c.foo(); // prints "A func"
return 0;
}
Of course, the code itself in the question doesn't require this at all, as the other answers have pointed out.

Just use virtual inheritance, so that the A subobject provided by B is the same object used in C.
Or write class C : public B... it will be implicitly usable as an A anyway, via the base class B.
Before the question was edited:
B::foo is not compatible with A::foo.
The required signature is
ReturnType /* missing from question */ foo(A* const this /* this parameter is implicit */);
But B::foo has the signature
ReturnType foo(B* const this);
An A*, which will be passed to the virtual function, is not a B*, which the implementation requires. If B inherited from A, then the compiler would generate B::foo to accept an A* const subobject and find the B* const this object from that subobject pointer. But B::foo has no knowledge of the relationship in C.

As you have the two base classes in your example (which might be a design issue/design smell, I'd review that) you have to explicitly call the implementation that you are after, be it A::foo() or B:foo().
If all B does is to provide the implementation of foo() I'd consider moving the implementation into A (you can provide an implementation for a pure virtual function) but even in this case you'd have to call it via its qualified name.

Related

Pure virtual function in class implementation [duplicate]

My basic understanding is that there is no implementation for a pure virtual function, however, I was told there might be implementation for pure virtual function.
class A {
public:
virtual void f() = 0;
};
void A::f() {
cout<<"Test"<<endl;
}
Is code above OK?
What's the purpose to make it a pure virtual function with an implementation?
A pure virtual function must be implemented in a derived type that will be directly instantiated, however the base type can still define an implementation. A derived class can explicitly call the base class implementation (if access permissions allow it) by using a fully-scoped name (by calling A::f() in your example - if A::f() were public or protected). Something like:
class B : public A {
virtual void f() {
// class B doesn't have anything special to do for f()
// so we'll call A's
// note that A's declaration of f() would have to be public
// or protected to avoid a compile time problem
A::f();
}
};
The use case I can think of off the top of my head is when there's a more-or-less reasonable default behavior, but the class designer wants that sort-of-default behavior be invoked only explicitly. It can also be the case what you want derived classes to always perform their own work but also be able to call a common set of functionality.
Note that even though it's permitted by the language, it's not something that I see commonly used (and the fact that it can be done seems to surprise most C++ programmers, even experienced ones).
To be clear, you are misunderstanding what = 0; after a virtual function means.
= 0 means derived classes must provide an implementation, not that the base class can not provide an implementation.
In practice, when you mark a virtual function as pure (=0), there is very little point in providing a definition, because it will never be called unless someone explicitly does so via Base::Function(...) or if the Base class constructor calls the virtual function in question.
The advantage of it is that it forces derived types to still override the method but also provides a default or additive implementation.
If you have code that should be executed by the deriving class, but you don't want it to be executed directly -- and you want to force it to be overriden.
Your code is correct, although all in all this isn't an often used feature, and usually only seen when trying to define a pure virtual destructor -- in that case you must provide an implementation. The funny thing is that once you derive from that class you don't need to override the destructor.
Hence the one sensible usage of pure virtual functions is specifying a pure virtual destructor as a "non-final" keyword.
The following code is surprisingly correct:
class Base {
public:
virtual ~Base() = 0;
};
Base::~Base() {}
class Derived : public Base {};
int main() {
// Base b; -- compile error
Derived d;
}
You'd have to give a body to a pure virtual destructor, for example :)
Read: http://cplusplus.co.il/2009/08/22/pure-virtual-destructor/
(Link broken, use archive)
Pure virtual functions with or without a body simply mean that the derived types must provide their own implementation.
Pure virtual function bodies in the base class are useful if your derived classes wants to call your base class implementation.
Yes this is correct. In your example, classes that derive from A inherit both the interface f() and a default implementation. But you force derived classes to implement the method f() (even if it is only to call the default implementation provided by A).
Scott Meyers discusses this in Effective C++ (2nd Edition) Item #36 Differentiate between inheritance of interface and inheritance of implementation. The item number may have changed in the latest edition.
The 'virtual void foo() =0;' syntax does not mean you can't implement foo() in current class, you can. It also does not mean you must implement it in derived classes.
Before you slap me, let's observe the Diamond Problem:
(Implicit code, mind you).
class A
{
public:
virtual void foo()=0;
virtual void bar();
}
class B : public virtual A
{
public:
void foo() { bar(); }
}
class C : public virtual A
{
public:
void bar();
}
class D : public B, public C
{}
int main(int argc, const char* argv[])
{
A* obj = new D();
**obj->foo();**
return 0;
}
Now, the obj->foo() invocation will result in B::foo() and then C::bar().
You see... pure virtual methods do not have to be implemented in derived classes (foo() has no implementation in class C - compiler will compile)
In C++ there are a lot of loopholes.
Hope I could help :-)
If I ask you what's the sound of an animal, the correct response is to ask which animal, that's exactly the purpose of pure virtual functions, or abstract function is when you cannot provide an implementation to your function in the base class (Animal) but each animal has its own sound.
class Animal
{
public:
virtual void sound() = 0;
}
class Dog : public Animal
{
public:
void sound()
{
std::cout << "Meo Meo";
}
}
One important use-case of having a pure virtual method with an implementation body, is when you want to have an abstract class, but you do not have any proper methods in the class to make it pure virtual. In this case, you can make the destructor of the class pure virtual and put your desired implementation (even an empty body) for that. As an example:
class Foo
{
virtual ~Foo() = 0;
void bar1() {}
void bar2(int x) {}
// other methods
};
Foo::~Foo()
{
}
This technique, makes the Foo class abstract and as a result impossible to instantiate the class directly. At the same time you have not added an additional pure virtual method to make the Foo class abstract.

how to override a function (in an abstract base class) with a covariant parameter

I have several classes D with public sections of the form:
class D
{
public:
D& foo();
void bar(D&);
}
I'd like to create a single abstract class from which they all derive.
My (naive) attempt was:
// in .h file
class B
{
public:
virtual B& foo() = 0;
virtual void bar(B&) = 0;
}
class D : public B
{
public:
D& foo() override;
void bar(D&) override;
}
// in .cpp file
D& D::bar() {return *(new D());}
void D::foo(D& d) {}
This failed to compile for (what I eventually realized was) a fairly sensible reason: Any function overriding the function
void bar(B&)=0;
must be defined for any parameter which is a reference to type B. The supplied candidate
virtual void bar(D&) override;
is only defined for (the smaller collection) of parameters which are references to type D.
Note that this is not a problem with the function foo. Indeed, if you comment out the three lines with bar, everything compiles fine.
I think that the technical explanation for this phenomenon is that C++ does not support covariance in parameters (but it does support contravariance in parameters).
The answer to the post C++ covariance in parameters suggests that I can't define an interface (i.e. an abstract class) for my classes D.
Is there some simple or conventional way to create a single "interface" for all my classes D? Alternatively, perhaps there is a different design pattern for hiding the different implementations of these classes.
Thanks in advance for your comments and suggestions.
dan
You can't, and for good reason. A derived class can't add preconditions that are more restrictive than the interface it derives from without breaking every principle of OOP that exists. By requiring the parameter to be more specific in your implementation of the interface this is exactly what you are doing.
An argument could be made that something like this could be useful:
struct IfaceA {};
struct IfaceB : IfaceA {};
struct Base { void f(IfaceB &); };
struct Derived : Base { void f(IfaceA &); };
This lessens preconditions rather than increase them, so it's OK. It's simply not done in C++, or any other language I'm aware of for that matter, so you just can't do it.
In both cases you can make an overload with the alternative parameter type and call the overridden version.
It's the opposite case with return types. Return values are post-conditions. You can make post conditions more specific, but can't make them more broad. So you can return your derived type but can't broaden it by returning a more abstract type. C++ implements covariant returns though at least one, very commonly used compiler does it very badly so that there are numerous bugs.
Based on the code that you have provided you have tried to override two diferent function signatures.
The best option you have is use the same signature, and then cast the result.
A simple example,
// in .h file
class B
{
public:
virtual B* foo() = 0;
virtual void bar(B*) = 0;
};
class D : public B
{
public:
B* foo() override;
void bar(B*) override;
};
// in .cpp file
B* D::foo()
{
D* p=new D();
return p;
}
void D::bar(B* d)
{
D* casted=dynamic_cast<D*>(d);
}
int main(void)
{
D son;
B* father=dynamic_cast<B*>(son.foo());
}
I hope that this can solve your problem, or at least give you a clue.
Could you use a templated base class?
template <typename Deriving>
struct Base {
virtual Deriving& foo() = 0;
virtual void bar(Deriving&) = 0;
};
struct Deriving : public Base<Deriving> {
...
};
You don't have a single interface class, but there is a single interface template, which is sometimes versatile enough.

a way in c++ to hide a specific function

i have an inheritance struct A : public B, i want to hide individual functions from B, is this possible?
i know the opposite is possible using using BMethod in the A declaration.
cheers
If you want to selectively hide functions from B it does not make much sense to use public inheritance in the first place.
Use private inheritance & selectively bring methods from B into the scope of A:
struct B{
void method1(){};
void method2(){};
};
struct A : private B{
using B::method1;
};
A a;
a.method1();
a.method2(); //error method2 is not accesible
There is an issue here: this would be a direct violation of the Liskov Substitution Principle, namely A would not act as a B any longer.
If you wish to reuse B implementation, the solution is simply to do so:
class A
{
public:
void foo() { return b.foo(); }
void bar() { return b.bar(); }
// ...
private:
B b;
};
Don't abuse inheritance, use composition instead
The using keyword can be used to change visibility
struct A
{
void method1();
};
struct B: public A
{
void method2();
private:
using A::method1;
};
Aside from the ways described in the previous answers—composition, private inheritance, and non-private inheritance but with the inherited method declared private—another way is to explicitly delete the inherited method:
#include <iostream>
struct A {
void foo() { std::cout << "foo\n"; }
};
struct B : A {
void foo() = delete;
};
int main() {
B b;
b.foo(); // COMPILER ERROR
}
Although the b.foo() call produces a compiler error, client code can still call the base class’s version by qualifying with the base class identifier A:
b.A::foo(); // compiles, outputs 'foo' to console
This explicit deletion way works when foo is not a virtual non-deleted method in A. By C++11 Standard §10.3/16, this explicit deletion is ill-formed when the deleted method in the derived class overrides a virtual non-deleted method of the base class. For more info on this restriction, see the answers to the SO question C++11 Delete Overriden Method.
You can't "hide it" per se, but you can make it a compile time error to call it. Example:
struct A
{
void AMethod() {}
};
class B : public A
{
void AMethod() {} //Hides A::AMethod
};
int main()
{
B myB;
myB.AMethod(); //Error: AMethod is private
static_cast<A*>(&myB)->AMethod(); //Ok
return 0;
}
Examples on codepad with the error, and without.
That all said, despite this being possible, you really shouldn't do it. You'll confuse the hell out of clients.
EDIT: Note that you can also do this with virtual functions (And with the error).
To those that are suggesting composition... this might not be the best possible way of going about things. My understanding is that the Liskov Substitution Principle only states that there's the possibility of the functions from the base class being used on the child, not that they necessarily should be. For example, for a particular base class you may have multiple functions that essentially perform the same operation, but for different specific cases. In the derived class you may want to abstract these public functions away in favor of simplifying the user's interface. This is where private inheritance can be used. Private inheritance might also be a necessity, if we have protected functions in the base class that we don't want the user of the base class to call, yet would be invaluable to the derived class.
In short, if you HAVE to, use private inheritance, but composition is preferred in most cases.
There is yet another approach.
class A{
void f1();
void f2();
void f3();
}
class BInterface{
void f2();
void f3();
}
class B : public A, BInterface
{
}
BInterface b = new B();
b->f1(); //doesn't work since f1 is not declared in BInterface
b->f2(); //should work
b->f3(); //should work
delete(b);
Use BInterface as a filter for inherited classes to exclude undesirable methods. Liskov Substitution principle isn't violated in this case since an object of BInterface class is not an object of A class even though that an object of B class is an object of BInterface class.
If the methods are private in B, then they will remain hidden to a even if you use public inheritance.
Can't alter the visibility of the original method.
You could create a method in struct A with the same name and have that method be private, but that doesn't prevent the method from being called when an instance of struct A is being referenced by a variable of type B.
Why don't you make it Virtual in the base class and override it in its Children? (more help)

Friendness and derived class

Let's say I have the following class hierarchy:
class Base
{
protected:
virtual void foo() = 0;
friend class Other;
};
class Derived : public Base
{
protected:
void foo() { /* Some implementation */ };
};
class Other
{
public:
void bar()
{
Derived* a = new Derived();
a->foo(); // Compiler error: foo() is protected within this context
};
};
I guess I could change it too a->Base::foo() but since foo() is pure virtual in the Base class, the call will result in calling Derived::foo() anyway.
However, the compiler seems to refuse a->foo(). I guess it is logical, but I can't really understand why. Am I missing something ? Can't (shouldn't) it handle this special case ?
Thank you.
When you qualify a method name with a class name, as in Base::foo() dynamic dispatch (run-time binding) does not apply. It will always call the Base implementation of foo(), no matter if foo() is virtual or not. Since in this case it is pure virtual, there is no implementation and the compiler complains.
Your second problem is that in C++, friendship is not inherited. If you want Other to have special access to Derived, it needs to be a friend of Derived specifically.
This, on the other hand, works:
Base* a = new Derived();
a->foo();
Because here, you are calling foo() on a Base* where foo() is public, and since you are not qualifying foo() with a class name, it uses dynamic dispatch and ends up calling the Derived version of Foo.
I guess You could do this
void bar()
{
Base* a = new Derived();
a->foo();
};
However, the compiler seems to refuse that.
Refuse what? It sounds like you are saying that the compiler is refusing to allow Other to call the foo() function through a Base pointer. That certainly shouldn't be the case.
To answer your basic question, friendship is not inherited....period. Permission scope is checked at the same stage as name resolution and since foo() is protected within the names you are using, you can't call it.
Polymorphism on the other hand is resolved through pointer redirection and has nothing to do with name resolution or access permission.
Try put this "friend class Other;" in the derived class.
Update: Now think of it, I agree with Tyler that you should change a to a Base pointer.
Base* a = new Derived();
It's unfortunate, but friendliness is inherently broken in C++ in my opinion:
Not inherited
Give unrestricted access to all the internals, no possibility to restrict it
I've given up using it "as-is" and I now mostly use the Key pattern (for lack of a better name).
///
/// Key definition
///
class Friend;
class FriendKey: boost::noncopyable { friend class Friend; FriendKey() {} };
///
/// Base/Derived definition
///
class Base
{
public:
void mySpecialMethod(const FriendKey&) { this->mySpecialMethodImpl(); }
private:
virtual void mySpecialMethodImpl() = 0;
}; // class Base
class Derived: public Base
{
public:
private:
virtual void mySpecialMethodImpl() {}
}; // class Derived
///
/// Friend definition
///
class Friend
{
public:
void mySpecialCall()
{
Derived d;
d.mySpecialMethod(FriendKey());
}
}; // class Friend
The concept is simple: each class declares a key (possible even in the forward header), and those that wish to grant special access to them will only make it possible for this key.
It's not perfect, because you can of course abuse it (by transitivity of the key). But then in C++ you can abuse everything, so it's more a problem of protected against Murphy than Machiavelli.

Pure virtual function with implementation

My basic understanding is that there is no implementation for a pure virtual function, however, I was told there might be implementation for pure virtual function.
class A {
public:
virtual void f() = 0;
};
void A::f() {
cout<<"Test"<<endl;
}
Is code above OK?
What's the purpose to make it a pure virtual function with an implementation?
A pure virtual function must be implemented in a derived type that will be directly instantiated, however the base type can still define an implementation. A derived class can explicitly call the base class implementation (if access permissions allow it) by using a fully-scoped name (by calling A::f() in your example - if A::f() were public or protected). Something like:
class B : public A {
virtual void f() {
// class B doesn't have anything special to do for f()
// so we'll call A's
// note that A's declaration of f() would have to be public
// or protected to avoid a compile time problem
A::f();
}
};
The use case I can think of off the top of my head is when there's a more-or-less reasonable default behavior, but the class designer wants that sort-of-default behavior be invoked only explicitly. It can also be the case what you want derived classes to always perform their own work but also be able to call a common set of functionality.
Note that even though it's permitted by the language, it's not something that I see commonly used (and the fact that it can be done seems to surprise most C++ programmers, even experienced ones).
To be clear, you are misunderstanding what = 0; after a virtual function means.
= 0 means derived classes must provide an implementation, not that the base class can not provide an implementation.
In practice, when you mark a virtual function as pure (=0), there is very little point in providing a definition, because it will never be called unless someone explicitly does so via Base::Function(...) or if the Base class constructor calls the virtual function in question.
The advantage of it is that it forces derived types to still override the method but also provides a default or additive implementation.
If you have code that should be executed by the deriving class, but you don't want it to be executed directly -- and you want to force it to be overriden.
Your code is correct, although all in all this isn't an often used feature, and usually only seen when trying to define a pure virtual destructor -- in that case you must provide an implementation. The funny thing is that once you derive from that class you don't need to override the destructor.
Hence the one sensible usage of pure virtual functions is specifying a pure virtual destructor as a "non-final" keyword.
The following code is surprisingly correct:
class Base {
public:
virtual ~Base() = 0;
};
Base::~Base() {}
class Derived : public Base {};
int main() {
// Base b; -- compile error
Derived d;
}
You'd have to give a body to a pure virtual destructor, for example :)
Read: http://cplusplus.co.il/2009/08/22/pure-virtual-destructor/
(Link broken, use archive)
Pure virtual functions with or without a body simply mean that the derived types must provide their own implementation.
Pure virtual function bodies in the base class are useful if your derived classes wants to call your base class implementation.
Yes this is correct. In your example, classes that derive from A inherit both the interface f() and a default implementation. But you force derived classes to implement the method f() (even if it is only to call the default implementation provided by A).
Scott Meyers discusses this in Effective C++ (2nd Edition) Item #36 Differentiate between inheritance of interface and inheritance of implementation. The item number may have changed in the latest edition.
The 'virtual void foo() =0;' syntax does not mean you can't implement foo() in current class, you can. It also does not mean you must implement it in derived classes.
Before you slap me, let's observe the Diamond Problem:
(Implicit code, mind you).
class A
{
public:
virtual void foo()=0;
virtual void bar();
}
class B : public virtual A
{
public:
void foo() { bar(); }
}
class C : public virtual A
{
public:
void bar();
}
class D : public B, public C
{}
int main(int argc, const char* argv[])
{
A* obj = new D();
**obj->foo();**
return 0;
}
Now, the obj->foo() invocation will result in B::foo() and then C::bar().
You see... pure virtual methods do not have to be implemented in derived classes (foo() has no implementation in class C - compiler will compile)
In C++ there are a lot of loopholes.
Hope I could help :-)
If I ask you what's the sound of an animal, the correct response is to ask which animal, that's exactly the purpose of pure virtual functions, or abstract function is when you cannot provide an implementation to your function in the base class (Animal) but each animal has its own sound.
class Animal
{
public:
virtual void sound() = 0;
}
class Dog : public Animal
{
public:
void sound()
{
std::cout << "Meo Meo";
}
}
One important use-case of having a pure virtual method with an implementation body, is when you want to have an abstract class, but you do not have any proper methods in the class to make it pure virtual. In this case, you can make the destructor of the class pure virtual and put your desired implementation (even an empty body) for that. As an example:
class Foo
{
virtual ~Foo() = 0;
void bar1() {}
void bar2(int x) {}
// other methods
};
Foo::~Foo()
{
}
This technique, makes the Foo class abstract and as a result impossible to instantiate the class directly. At the same time you have not added an additional pure virtual method to make the Foo class abstract.