So, based on a cursory search, I already know that calling a virtual function (pure or otherwise) from a constructor is a no go. I have restructured my code to ensure that I am not doing that. While this causes the user of my classes to add an extra function call in their code, this is really not that big of a deal. Namely, instead of calling the constructor in a loop, they now call the function which (in fact!) increases performance of the code since we don't have the housekeeping of building and destroying the object in question every time.
However, I have stumbled across something interesting...
In the abstract class I have something like this:
// in AbstractClass.h:
class AbstractClass {
public:
AbstractClass() {}
virtual int Func(); //user can override
protected:
// Func broken up, derived class must define these
virtual int Step1() = 0;
virtual int Step2() = 0;
virtual int Step3() = 0;
// in AbstractClass.cpp:
int AbstractClass::Func() {
Step1();
// Error checking goes here
Step2();
// More error checking...
// etc...
}
Basically, there is a common structure that the pure virtual functions follow most of the time, but if they don't Func() is virtual and allows the derived class to specify the order. However, each step must be implemented in derived classes.
I just wanted to be sure that there's nothing that I necessarily am doing wrong here since the Func() function calls the pure virtual ones. That is, using the base class, if you call StepX(), bad things will happen. However, the class is utilized by creating a derived object and then calling Func() (e.g. MyDerivedObject.Func();) on that derived object, which should have all the pure virtual functions overloaded properly.
Is there anything that I'm missing or doing incorrectly by following this method? Thanks for the help!
Func is calling the virtual ones, not the pure virtual ones. You would have to qualify the calls with a scope operator, i.e. AbstractClass::Step1() to call THAT (virtual pure) function. Since you are not, you will always get an implementation by a derived class.
A virtual function in a base class makes the derived classes able to override it. But it seems things stop there.
But if the base class virtual function is pure, that forces the derived classes to implement the function.
As a side comment you can make the Step1, Step2, Step3 methods private so that you'll be prevented by the compiler from directly calling them.
Related
Pure virtual functions are a must-have property for abstract base classes. So no implementations should be made, which is very intuitive to understand. But Recently I came to know that pure virtual functions can still be defined later and be invoked statically(not by object instances). I can't think up a reason for this. If one virtual function is defined as pure, then what's the reason to implement it?
class A{
public:
...
virtual void interface() = 0; //Pure Virtual functions
...
}
void A::interface() //Implementation
{
cout<<"This the implementation for A interface";
}
I am curious about the logic behind this. Why is c++ designed like this way?
It might make sense to have a "default" implementation, which concrete classes can use if it's useful to them. They still need to override it, but can call the base-class version non-virtually:
struct B : A {
void interface() {
A::interface(); // call the default implementation
// and maybe do some B-specific things too
}
};
I can't think up a reason for this. If one virtual function is defined as pure, then what's the reason to implement it?
The purpose of a pure virtual function is not to prohibit definitions. It is to mark the class as uninstantiable.
Providing a definition may be useful for deriving classes:
struct A
{
virtual void foo() = 0;
};
void A::foo()
{
/* some common logic here */
}
struct B : A
{
virtual void foo() overrides
{
bar();
A::foo();
}
void bar();
};
struct C : A
{
virtual void foo() overrides
{
baz();
A::foo();
}
void baz();
};
A pure virtual function simply means that the function must be overidden by all derived classes it does not mean that the function cannot/should not have a implementation of its own. Two most obvious cases for such a pure virtual function having implementation are:
A Derived class implementation can call Base class implementation
Sometimes you would want a base class to be made abstract but there is no method which you can mark as pure virtual in such a case a destructor is most obvious choice but in such a destructor still needs a implementation.
interface() = 0 means derived classes must provide an implementation, so the definition effects derived classes, but the base class is permitted to have an implementation of the method so that derived classes can always call base::interface().
You apparently completely misunderstood the meaning of the term "statically" in this context.
Yes, pure virtual functions can still have bodies, i.e. they can still be defined.
And no, you cannot invoke such function "without an object instance", as you seem to incorrectly believe. A pure virtual function with a body is still a non-static member function. It still requires an object instance to be invoked.
When someone says that such function can be invoked "statically", it means that it can be called directly, without using virtual dispatch mechanism. Function calls that go through virtual dispatch are sometimes called "virtual calls" or "dynamic calls", while direct function calls are sometimes called "static calls". The term "static" in this context assumes a completely different meaning, not connected in any way to static member functions.
In C++ language a direct non-virtual (i.e. "static") call can be performed explicitly by specifying a qualified member name in the call. For example, if class B derives from your class A, then inside some method B::foo() you can use the following syntax
void B::foo() {
A::interface(); // <- qualified method name
}
which performs a direct call to the implementation of A::interface() you provided. For an object b of type B the same kind of call can be performed as
B b;
b.A::interface(); // <- qualified method name
In both cases the call is performed for a specific object (*this in the first example, and b in the second).
Pretty much the same thing happens implicitly when destructors of derived classes call destructors of base class, which is why you will often encounter this situation with pure virtual destructors (i.e. they are declared as pure virtual, yet have a body).
There is an abstract class A which has a pure virtual member function func(). A great number of derived classes are present, each one with a different implementation of func().
Imagine now that you want to add an extra task to be carried out at each call of func(), let's say a cout << "hello world"; independently from the derived class. The task is also independent from the content of func() so it could be executed before, after or even in the middle of func(), only the fact that it gets executed once each call to func() matters.
Does c++(11) allow a smart way to do this?
The best thing that comes to my mind is to write a pre-func() method in the parent class where the task is implemented and copy a call to pre-func() at the beginning of all the func() implementations in the derived classes. Anything better?
I believe you could use the Non-virtual interface idiom
You'd have the base class as follow:
class A{
public:
void myFunc();
private:
virtual void myVirtualFunc();
}
with notably the following in the .cpp :
void A::myFunc(){
//stuff
myVirtualFunc();
//stuff
}
Then each derived class can reimplement myVirtualFunc() and change its behavior. The virtual is private so you're guaranteed it won't be called anywhere but in the public non-virtual defined by the base class (guaranteeing that the code you need to run for each call will be ran), and the private visibility doesn't prevent the derived class from reimplementing it. The derived class can specify what the virtual does, not where (though as mentioned by #WhozCraig, the derived class still can reimplement the virtual function as public).
If I understand the question correctly one option available to you is to create the "pre-func()" method in the base class and have that function print "Hello World" and then call "func()". That way your derived classes all override "func()" but you invoke the API through "pre-func()" (obviously I wouldn't use the term pre-func as it no longer describes the functionality accurately)
I have a class declared as follow:
class TestFoo {
public:
TestFoo();
virtual void virtualFunction();
void nonVirtualFunction();
};
that I try to implement this way
TestFoo::TestFoo(){}
void TestFoo::nonVirtualFunction(){}
which on compilation returns the error:
undefined reference to vtable for TestFoo
I tried :
TestFoo::TestFoo(){}
void TestFoo::nonVirtualFunction(){}
void TestFoo::virtualFunction(){}
which compiles ok which is consistent to the answers to these posts:
Undefined reference to vtable
undefined reference to vtable
What confuses me is that I thought the whole point of declaring a virtual function is that I would not need to define it. In this example, I am not planning to create any instance of TestFoo, but to create instances of (concrete) classes inheriting from TestFoo. But still, I want to define the function nonVirtualFunction for every subclasses of TestFoo.
Something I did not get right ?
Thanks !
the whole point of declaring a virtual function is that I would not
need to define it
Not quite, it says "I may want to replace the implementation of this function by something else in a derived class."
I may have misunderstood your question, but you seem to imply that you don't think you can define pure virtual member function in C++, which you can. You can declare one as follows.
virtual void virtualFunction() = 0;
Normally, a pure virtual function won't be defined, but of course you can. That says "There is no default implementation of this function because it won't always make sense, but I'll provide you with an implementation that you can opt into."
By the way, if a class has any virtual functions, you should also define a virtual destructor, as it is perfectly legal (and often recommended) to have a base class (smart) pointer to a derived class - without a virtual destructor, the object may not be deleted correctly.
... I thought the whole point of declaring a
virtual function is that I would not need to define it ...
For that facility you have a feature called pure virtual methods:
virtual void virtualFunction() = 0; // no linking error now
Note that, a virtual method cannot remain unimplemented. The reason is that for every virtual method declared inside a class body there has to be a vtable entry. Failing to find its body results in linking error.
Purpose of this restriction:
Unless a class is abstract - that is it has at least one virtual function - there is no way you can guarantee to the compiler that you are not going to declare an object of TestFoo. What happens when you do following:
DerivedOfTestFoo obj1;
TestFoo obj2 = obj1, *p = &obj2; // object slicing
p->virtualFunction(); // where is the body?
Other situation; in constructor there is no virtual mechanism:
TestFoo::TestFoo () {
this->virtualFunction(); // where is the body?
}
We can conclude that, compilers follow the rule, "Better to be safe than sorry". :)
Your description matches perfectly with the case of an abstract class. Declare your virtual function as:
virtual void VirtualFunction () = 0;
This means that you are not implementing the function in this class. As a result, the class becomes abstract. That is, no bare objects of this class can be instantiated.
Also, you should provide a virtual destructor.
Update: Some clarifications...
The language allows you to redefine a non-virtual function. Though, the wrong version might be called in some cases:
derived D; // rB is a reference to base class but it
base & rB=D; // points to an object of the derived class
rB.NonVirtualFunction (); // The base-class version is called
For this reason, redefining a non-virtual function is strongly discouraged nowadays. See Scott Meyers' "Effective C++, Third Edition: 55 Specific Ways to Improve Your Programs and Designs", item 36: "Never redefine an inherited non-virtual function."
See also item 7: "Declare destructors virtual in polymorphic base classes". An example:
base * pB = new derived;
delete pB; // If base's destructor is not virtual,
// ~derived() will not be called.
In case you wonder why isn't everything virtual by default, the reason is that calling a virtual function is slightly slower than calling a non-virtual one. Oh, and objects of classes with virtual functions occupy a few more bytes each.
If you want make this virtual function as pure virtual function,do not want to define it then, virtual void virtualFunction() = 0;
I have some code where I really want to call a virtual method from a constructor. I know this is considered unsafe, and I know enough about object construction to also understand why. I also am not experiencing these problems. Currently my code is working and I think it should be fine, but I want to make sure.
Here is what I am doing:
I have some class hierarchy and there is a normal public function which just forwards to a private virtual method, as usual. However I do want to call this public method upon construction of my objects, because it is filling all data into the object. I will be absolutely sure that this virtual call comes from the leaf class, because using this virtual method from any other part of the class hierarchy simply does not make sense at all.
So in my opinion the object creation should be finished once I am doing the virtual call and everything should be fine. Is there still anything that could go wrong? I guess I'll have to mark this part of the logic with some big comments to explain why this logic should never ever be moved to any of the base clases, even though it looks like it could be moved. But other than stupidity of other programmers I should be fine, shouldn't I?
It is absolutely safe to call any non-abstract virtual function in the constructor or the destructor! However, its behavior may be confusing as it may not do what is expected. While the constructor of a class is executed, the static and dynamic type of the object is the type of the constructor. That is, the virtual function will never be dispatched to the override of a further derived class. Other than that, virtual dispatch actually works: e.g. when calling a virtual function via a base class pointer or reference correctly dispatches to the override in the class being currently constructor or destructed. For example (probably riddled with typos as I currently can't this code):
#include <iostream>
struct A {
virtual ~A() {}
virtual void f() { std::cout << "A::f()\n"; }
void g() { this->f(); }
};
struct B: A {
B() { this->g(); } // this prints 'B::f()'
void f() { std::cout << "B::f()\n"; }
};
struct C: B {
void f() { std::cout << "C::f()\n"; } // not called from B::B()
};
int main() {
C c;
}
That is, you can call a virtual function, directly or indirectly, in the constructor or a destructor of a class if you don't want the virtual function to be dispatched to a further derived function. You can even do this is virtual function is abstract in the given class as long as it is defined. However, having an undefined abstract function being dispatched to will cause a run-time error.
When a constructor is called, the class is set up to be an instance of that class but not the derived class. You cannot call into a virtual function of a derived class from a base constructor. By the time you get to the constructor of the most derived class, all of the virtual functions should be safe to call.
If you wish to ensure that someone can't make an incorrect call, define the virtual function in the base class and have it assert and/or throw an exception when it is called.
The rule isn't so much that you need to be in a leaf class as to realize that when you make a member call from Foo::Foo(..), the object is exactly a Foo, even if it's on its way to being a Bar (assuming Foo is derived from Bar and you're constructing a Bar instance). That's 100% reliable.
Otherwise, the fact that the member is virtual isn't all that significant. There are other pitfalls that happen just as well with non-virtual functions: if you were to call a virtual or non-virtual method that assumed the object was completely constructed but called it within the constructor before that was the case, you'd also have problems. These are just hard cases to pin down because not only must the function you call be okay, all the functions it calls must be okay.
It doesn't sound like you have a problem, it's just one of those places prone for errors to crop up.
When I declare a base class, should I declare all the functions in it as virtual, or should I have a set of virtual functions and a set of non-virtual functions which I am sure are not going to be inherited?
A function only needs to be virtual iff a derived class will implement that function in a different way.
For example:
class Base {
public:
void setI (int i) // No need for it to be virtual
{
m_i = i;
}
virtual ~Base () {} // Almost always a good idea
virtual bool isDerived1 () // Is overridden - so make it virtual
{
return false;
}
private:
int m_i;
};
class Derived1 : public Base {
public:
virtual ~Derived () {}
virtual bool isDerived1 () // Is overridden - so make it virtual
{
return true;
}
};
As a result, I would error the side of not having anything virtual unless you know in advance that you intend to override it or until you discover that you require the behaviour. The only exception to this is the destructor, for which its almost always the case that you want it to be virtual in a base class.
You should only make functions you intend and design to be overridden virtual. Making a method virtual is not free in terms of both maintenance and performance (maintenance being the much bigger issue IMHO).
Once a method is virtual it becomes harder to reason about any code which uses this method. Because instead of considering what one method call would do, you must consider what N method calls would do in that scenario. N represents the number of sub classes which override that method.
The one exception to this rule is destructors. They should be virtual in any class which is intended to be derived from. It's the only way to guarantee that the proper destructor is called during deallocation.
The non-virtual interface idiom (C++ Coding Standards item 39) says that a base class should have non-virtual interface methods, allowing the base class to guarantee invariants, and non-public virtual methods for customization of the base class behaviour by derived classes. The non-virtual interface methods call the virtual methods to provide the overridable behaviour.
I tend to make only the things I want to be overridable virtual. If my initial assumptions about what I will want to override turn out to be wrong, I go back and change the base class.
Oh, and obviously always make your destructor virtual if you're working on something that will be inherited from.
If you are creating a base class ( you are sure that somebody derives the class ) then you can do following things:
Make destructor virtual (a must for base class)
Define methods which should be
derived and make them virtual.
Define methods which need not be ( or
should not be) derived as
non-virtual.
If the functions are only for derived
class and not for base class then mark
them as protected.
Compiler wouldn't know which actual piece of code will be run when pointer of base type calls a virtual function. so the actual piece of code that would be run needs to be evaluated at run-time according to which object is pointed by base class pointer. So avoid the use of virtual function if the function is not gonne be overriden in an inherited class.
TLDR version:
"you should have a set of virtual functions and a set of non-virtual functions which you are sure are not going to be inherited." Because virtual functions causes a performance decrease at run-time.
The interface functions should be, in general, virtual. Functions that provide fixed functionality should not.
Why declare something virtual until you are really overriding it? I believe it's not a question of being sure or not. Follow the facts: is it overriden somewhere? No? Then it must not be virtual.