CRTP vs overload and final - c++

I often use CRTP to call a derived class function from a base class. It has the bonus of not incurring the cost of a virtual function call, e.g:
template< class Derived >
class Base
{
public:
void foo()
{
static_cast<Derived*>(this)->foo_impl(); // Non virtual derived class call
}
};
class Derived : public Base<Derived>
{
private:
void foo_impl()
{
// Do Stuff
}
};
C++11 introduced the final language identifier which marks a virtual function (or class) as final, telling the compiler that there will be no further overrides of the function.
It is my understanding (from the Going Native 2013 presentations) that if a virtual function is marked as final the compiler can optimize the code to eliminate the overhead of the virtual function call.
Ergo In the example above the CRTP can be removed and the overhead of the virtual function call is still avoided, providing the derived class marks the virtual function as final i.e.:
class Base
{
public:
virtual void foo_impl() = 0;
void foo()
{
foo_impl(); // Non virtual derived class call
}
};
class Derived : public Base
{
public:
// function marked as final, no virtual function call overhead
virtual void foo_impl() final
{
// Do Stuff
}
};
If this is the case are there any recommendations as to which is the best approach?
Should CRTP still be preferred since it guarantees that function call is non virtual, where as optimizations based on final cannot be relied upon?

It depends on how you pass the instance around. Consider in one translation unit:
Derived d;
foo( &d );
and in another:
void foo( Base* b )
{
b->foo();
}
except for LTO, there is no chance for the compiler to remove the virtual call overhead.
If OTOH, you have:
void foo( Derived* d )
{
d->foo();
}
The compiler could now be smart enough to optimize the vtable lookup away as it has all the necessary information. I don't think it is guaranteed, though. Without final, the vtable lookup would still be necessary as d could point to something derived from Derived which has yet another implementation of foo_impl().

My 5cents on this:
Recent GCC optimize virtual functions when class name is known.
Also the standard say if class name is known, the virtual function may be inlined - e.g. no virtual dispatch.

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.

Using Virtual Function with Final keyword

I have a question about using the keyword final in C++. I understand that virtual function is a member function that is declared in the base class, and it is expected to be overridden in the derived classes. By dynamic binding, an appropriate method will be called, depending on the type of the object responsible for the call. However, to prevent a member function in a base class from being overridden in any derived class, we will use the final keyword.
void startEngine() final;// Compile error!
virtual void startEngine() final; //No error
Why we use "final" to PREVENT a member function in the base class from being overridden in derived class meanwhile we still have to use the keyword VIRTUAL (ALLOW to override) together.
I tried to delete the word virtual, but I got a compile error: "nonvirtual function cannot be declared with 'final' modifier"
First at all, we only can stop overriding functions if they can be overridden at all. So final only makes sense on virtual functions at all.
Still, final applied on a single class's virtual function might appear pretty meaningless. But if you consider a more complex hierarchy, matter changes:
class Parent
{
public:
virtual ~Parent() = default;
virtual void f();
};
class Child : public Parent
{
public:
void f() final; // f IS virtual already...
};
class GrandChild : public Child
{
// cannot override f any more – while Child still could!
};
Additionally, consider the following:
class Base
{
public:
virtual ~Base() = default;
void f(); // non-virtual! (i. e. cannot be overridden)
};
class Derived : public Base
{
public:
void f(); // does not override, but HIDEs Base::f!!!
};
Declaring Base::f both virtual and final would prevent hiding as well (but not overloading).
Actually, again this scenario rather makes sense if Base itself already inherited from another polymorphic class. If not and Base is not intended to be inherited, I'd not introduce any virtual functions at all (virtual function calls are more costly than normal function calls!). If then a user still inherits and hides a function – well, his own responsibility...

What's the potential danger of overriding a private function to public?

I just find out that overriding a private function to a public one from base object is allowed in C++ since Visual Studio produces 0 warning. Is there any potential danger to doing that?
If there isn't, what's the difference between declaring a virtual function in private, protected and public in a base object?
what's the difference between declaring a virtual function in
private, protected and public in a base object?
The difference is that a private virtual function can be called only from a base class. This can be useful if the function is not a part of an external class interface, and is only used by base class. So that users call (some other) base class' member, and that member calls the virtual function. For example:
class Base {
virtual void stage1()=0; // derived classes override this
virtual void stage2()=0;
public:
void run() { stage1(); stage2(); } // users call this
};
Moreover, there is a point of view that you should not make your virtual functions public at all, because the fact that they are virtual is internals of the class and its subclasses, and the users should not be aware of that. It is rarely that the same function must be overridden and callable from external code. This allows the base class to control which (virtual) functions can be called from which (non-virtual) public method, making maiteinance easier.
See more details in this article by Herb Sutter:
...each [public] virtual
function is doing two jobs: It's specifying interface because it's
public...; and it's specifying implementation detail,
namely the internally customizable behavior... That a public virtual
function inherently has two significantly different jobs is a sign
that it's not separating concerns well and that we should consider a
different approach. What if we want to separate the specification of
interface from the specification of the implementation's customizable
behavior?
...
In summary, prefer to make base class virtual functions private (or
protected if you really must). This separates the concerns of
interface and implementation, which stabilizes interfaces and makes
implementation decisions easier to change and refactor later.
However, I am not qualified to say whether this is really widely used...
Is there any potential danger to doing that?
I don't think so, because you are still very limited:
class Base
{
private:
virtual void foo(){}
};
class Derived1 : public Base
{
public:
virtual void foo(){ Base::foo(); }
};
class Derived2 : public Base
{
public:
virtual void foo(){}
};
int main()
{
Derived1 d1;
d1.foo(); //error
Base * d2 = new Derived2();
d2->foo(); //error
}
So at best you will be able to call the overloaded function (if it doesn't call the function from the base class from itself), but the function of the base class will still have the same visibility, and will be inaccessible.
When changing access visibility by overriding in derived class, base class visibility doesn't change:
So with:
class Base {
public:
virtual ~Base() = default;
protected:
virtual void foo() = 0;
};
class Derived : public Base {
public:
void foo() override {};
};
Then
Derived d;
Base& b = d;
d.foo(); // valid
b.foo(); // invalid
If there isn't, what's the difference between declaring a virtual function in private, protected and public in a base object?
It depends on how you access the function. The type of the object/pointer you use determines whether you can access the function.
class Base
{
public:
virtual void foo() {}
};
class Derived : public Base
{
private:
virtual void foo() {}
};
int main()
{
Derived* dptr = new Derived;
Base* bptr = dptr;
dptr->foo(); // Can't use it. Derived::foo is private
bptr->foo(); // Can use it. Base::foo is public.
}
Compiler message, using g++ 4.9.3.
socc.cc: In function ‘int main()’:
socc.cc:12:20: error: ‘virtual void Derived::foo()’ is private
virtual void foo() {}
^
socc.cc:20:14: error: within this context
dptr->foo(); // Can't use it. Derived::foo is private
A virtual function is a customization point for derived class implementations. If it is private then it's purely an implementation detail. Making it more accessible in a derived class then exposes an implementation detail, with all that that entails. In particular client code can come to depend on that detail so that the implementation can't be easily changed. It can also be easier for client tode to call in incorrect ways, than the originally intended interface, and it can yield results that are only valid in certain contexts, so that it's more brittle than the original interface.

CRTP Dispatch in C++11

Say I have the following code:
template <class Derived>
class Base {
public:
virtual void foo_impl() = 0;
void foo() {
static_cast<Derived*>(this)->foo_impl(); //A
(*static_cast<Derived*>(this)).foo_impl(); //B
}
};
class Derived : public Base<Derived> {
private:
void foo_impl() {
bar();
}
};
A few questions:
Will line A generate a virtual function call? Although the majority of what I can find on the internet recommends doing things this way, to me I don't see how the compiler can do static dispatch considering that a pointer to Derived could still actually point to an object of type Derived2 where Derived2 : public Derived.
Does line B fix the issue I brought up in my previous point (if applicable)? It seems like it would, considering that now the call is not on a pointer any more and thus using *. would avoid a virtual function call. But if the compiler treats the dereferenced cast as a reference type, it could still generate a virtual function call... in that case, what is the workaround?
Does adding the C++11 final keyword to foo_impl() change how the compiler would act in either (or any other relevant) case?
Will line A generate a virtual function call?
Yes. foo_impl() is virtual and Derived overrides it. Even though foo_impl() in Derived is not explicitly tagged as virtual, it is in the base class, and this is enough to make it a virtual function.
Does line B fix the issue I brought up in my previous point (if applicable)?
No. It does not matter if the call is on a pointer or on a reference: the compiler still won't know whether you are invoking the function foo_impl() on an instance of a class that derives from Derived, or on a direct instance of Derived. Thus, the call is performed through a vtable.
To see what I mean:
#include <iostream>
using namespace std;
template <class Derived>
class Base {
public:
virtual void foo_impl() = 0;
void foo() {
static_cast<Derived*>(this)->foo_impl();
(*static_cast<Derived*>(this)).foo_impl();
}
};
class Derived : public Base<Derived> {
public:
void foo_impl() {
cout << "Derived::foo_impl()" << endl;
}
};
class MoreDerived : public Derived {
public:
void foo_impl() {
cout << "MoreDerived::foo_impl()" << endl;
}
};
int main()
{
MoreDerived d;
d.foo(); // Will output "MoreDerived::foo_impl()" twice
}
Finally:
Does adding the C++11 final keyword to foo_impl() change how the compiler would act in either (or any other relevant) case?
In theory, yes. The final keyword would make it impossible to override that function in subclasses of Derived. Thus, when performing a function call to foo_impl() through a pointer to Derived, the compiler could resolve the call statically. However, to the best of my knowledge, compilers are not required to do so by the C++ Standard.
CONCLUSION:
In any case, I believe what you actually want to do is not to declare the foo_impl() function at all in the base class. This is normally the case when you use the CRTP. Additionally, you will have to declare class Base<Derived> a friend of Derived if you want it to access Derived's private function foo_impl(). Otherwise, you can make foo_impl() public.
The common idiom for the CRTP does not involve declaring the pure virtual functions in the base. As you mention in one of the comments, that means that the compiler will not enforce the definition of the member in the derived type (other than through use, if there is any use of foo in the base, that requires the presence of foo_impl in the derived type).
While I would stick to the common idiom and not define the pure virtual function in the base, but, if you really feel you need to do it, you can disable dynamic dispatch by adding extra qualification:
template <class Derived>
class Base {
public:
virtual void foo_impl() = 0;
void foo() {
static_cast<Derived*>(this)->Derived::foo_impl();
// ^^^^^^^^^
}
};
The use of the extra qualification Derived:: disables dynamic dispatch, and that call will be statically resolved to Derived::foo_impl. Note that this comes will all of the usual caveats: you have a class with a virtual function and paying the cost of the virtual pointer per object, but you cannot override that virtual function in a most derived type, as the use in the CRTP base is blocking dynamic dispatch...
The extra verbiage in lines A and B have absolutely no effect on
the generated code. I don't know who recommends this (I've never seen
it), but in practice, the only time it might have an effect is
if the function isn't virtual. Just write foo_impl(), and be
done with it.
There is a means of avoiding the virtual function call if the
compiler knows the derived type. I've seen it used for
vector-like classes (where there are different implementations,
e.g. normal, sparse, etc. of the vector):
template <typename T>
class Base
{
private:
virtual T& getValue( int index ) = 0;
public:
T& operator[]( int index ) { return getValue( index ); }
};
template <typename T>
class Derived : public Base<T>
{
private:
virtual T& getValue( int index )
{
return operator[]( index );
}
public:
T& operator[]( index )
{
// find element and return it.
}
};
The idea here is that you normally only work through references
to the base class, but if performance becomes an issue, because
you're using [] in a tight loop, you can dynamic_cast to the
derived class before the loop, and use [] on the derived
class.

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.