What i think about virtual class is, if a derived class has a public base, let's say, class base, then a pointer to derived can be assigned to a variable of type pointer to base without use of any explicit type conversion. But what if, we are inside of base class then how can we call derived class's functions. I will give an example:
class Graph{
public:
Graph(string);
virtual bool addEdge(string,string);
}
class Direct:public Graph{
public:
Direct(string);
bool addEdge(string,string);
}
Direct::Direct(string filename):Graph(filename){};
When i call constructor of Direct class then it calls Graph. Now lets think Graph function calls addedge.
Graph(string str){
addedge(str,str);
}
When it calls addedge, even if the function is virtual, it calls Graph::edge. What i want is, to call Direct::addedge. How can it be done?
It can't be done. Virtual functions cannot be called whithin constructors -- at least they cannot be called with virtual behavior. The problem is that the derived class constructor is responsible for setting up the vtbl to point to it's particular instance of the virtual functions. The base class' constructor is executed first, before the derived constructor, so a direct solution to this is not possible.
You can work around this using either some form of "init" function on your base class, or you can use a factory method.
This is by design in C++, see the C++ FAQ.
In your case i also don't see why you would need it - if you want to use an initialization helper function, there is no need for it to be virtual.
Your explanation is here in Scott Meyer's Effective C++
Don't call virtual functions during construction or destruction, because such calls will never go to a more derived class than that of the currently executing constructor or destructor.
It appears you want your base type's constructor to call down into the derived type through a virtual method. This is troublesome as the derived type hasn't yet been fully constructed. What is the derived type's overridden virtual function going to use for state when its type hasn't yet been constructed? You might want to look into another design pattern, such as a factory, that can encapsulate the two-step construct/initialize pattern if you really need it.
Related
Suppose I have an abstract class A. Is it possible for A to force any classes inheriting from it to implement a certain constructor prototype?
e.g.:
class A {
public:
// purely virtual function
virtual void func() = 0;
// what i would like to be able to do
virtual A(Obj) = 0;
};
While the purely virtual function func above is legal, the constructor A(Obj) cannot be virtual. I would like if instances of a class B inheriting from A will remain abstract (or some uninstantiable or erroneous equivalent) until B overrides the constructor A(Obj).
In other words, I want to force any subclass of A to implement a constructor that takes an Obj as an argument. Is this possible?
No, a subclass is free to implement any kind of a constructor that it wants.
The only responsibility a subclass's constructor has is to construct its superclasses.
So, it is possible for a superclass to influence, in a minor way, how its subclasses' constructors work. For example, if a class's constructor takes a parameter that's an instance of a class's inner class (a minor variation of your edited code example), the subclass is then required to instantiate the inherited inner class, in order to construct its superclass, or take an existing instance as a parameter, that it forwards to the superclass's constructor.
But that's, pretty much, as far as it goes. The subclass's constructors' signatures are completely out of the superclass's control.
I'm now learning C++, the OO side, and I see this all the time:
class SomeClass{
virtual void aMethod()=0;
}
class AnotherClass{
void anotherMethod(){/*Empty*/}
}
class SomeClassSon : public SomeClass{
void aMethod(){/*Also Empty*/}
}
what is the difference between the 3 methods? The virtual equals zero, the empty one, and the virtual, since it is inherited, empty one.
Why can't I just make the SomeClassSon method like the father, virtual void equals zero?
For your
class SomeClass{
virtual void aMethod()=0;
}
the presence of a pure virtual method makes your class abstract. Once you have one such pure virtual method, =0, in your class, you cannot instantiate the class. What is more, any derived class must implement the pure virtual aMethod(), or it becomes an abstract class as well.
In your derived class, you overwrite the pure virtual method from above, and this makes the derived class non abstract. You can instantiate this derived class.
But, in derived class, method's body is empty, right? That's why your question makes sense: why not make the class pure virtual as well. Well, your class may entail other methods. If so, SomeClass cannot be instantiated (there is a pure virtual method), whereas child class SomeClassSon can be.
Same applies to your AnotherClass, which can be instantiated, contrary to SomeClass.
The difference is that virtual void aMethod() = 0 is a pure virtual function, meaning that:
SomeClass becomes an abstract base class,
meaning it cannot be instantiated.
Any class which inherits from SomeClass must implement aMethod, or it too becomes an abstract base class which cannot be instantiated
Note that any class with one or more pure virtual functions is automatically an abstract base class.
The "equals 0" you're referring to is called "pure virtual". It's a function that the child that wants to be instantiated HAS to implement as opposed to providing base functionality meaning that the parent class is going to define functionality that has to exist but that the parent has no knowledge of how the child will do it. Note that this makes the class abstract in that it cannot be instantiated. For example I may want to define a "Mammal" class I can inherit from and I want its children to act a certain way - but I can't simply make a "Mammal". Instead I would create a "Giraffe" class and make sure it acts like it's supposed to.
It's also explained at this SO question.
The "Empty" function you're referring to is instead functionality where the function is defined and can be called - but does nothing.
the declaration aMethod()=0 tells the compiler that this method must be provided for in subclasses. Any subclass that does not implement the method can not be instantiated. This helps you ensure any objects of the base class will have the method implemented.
A pure virtual function (your first example, with the =0) means that function must be overridden in a derived class for an object of that class to be instantiated.
The second is basically just a member function that does nothing. Since the function has a different name and the class isn't related to SomeClass, the two don't affect each other at all.
The third overrides the pure virtual function, so it's possible to instantiate SomeClassSon, but in the derived class the overridden function does nothing.
A pure virtual makes the class abstract. An empty non-virtual method doesn't do anything - it just leads to a linker error if you attempt to call it. By contrast, you can't attempt to call a pure virtual (unless you attempt to call it from a constructor, which is bad anyway) because the compiler won't let you create that object.
There's also a logical difference - the method marked virtual will be virtual through the inheritance chain - the others are just regular methods.
I´m trying to accomplish the same which is described in a previous question:
virtual function call from base class
But, my real question is:
What if f() is the constructor in the Base class? Which g() will be called? I don´t know if I am doing wrong, but in my program it seems to be that is the opposite.
Taking the same variables from the previous question, a code which shows such
behavior would look like this:
Class Base
{
Base(){g();};
virtual void g(){//Do some Base related code;}
};
Class Derived : public Base
{
Derived(){};
virtual void g(){//Do some Derived related code};
};
int main()
{
Derived newDerived;
return 0;
}
Update:
Thanx to Naveen.
He provided me a page which contains all related information about this topic.
I´ll let you know the link here:
parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.6
Even though it's a virtual function, the base's version will get called since the derived class isn't fully constructed yet. The base class constructor is called before the derived class constructor, so if the derived virtual function were to get called, it would be with an incompletely-initialized instance - a possible (probably) recipe for disaster.
It will Base::g(). See this FAQ for explanation.
When your base class constructor is called, only the vtable for the base class is setup, so any virtual function calls will apply only to base class methods.
When the derived class constructor is called, calling a virtual function will call the derived class override, if any.
The virtual mechanism does not work in the constructors, so if you call even a virtual function from a base class constructor you will always end up calling the functions of the base class only. There are a few reasons why the virtual funcs do not work in the ctors:
While in the constructors the object has not been created fully.
ctors calls are resolved at compile time only, so they actually don't have any runtime dependency, so no use of virtual functions.
Unlike other functions ctors and dtors are not inherited, so every class has its own set of ctors and dtors, so there is no chance of overriding.
class base{}
class child : public base{
**dummyfunction();**
}
now I am calling a function in which I am passing a child class object.
**child ob;**
function(**ob**);//calling a function
//function body
function(**base *object**)
{
**//here I want to access the function of child class. How can I do it???**
**for example dummyfunction()**
}
You either need to put the function in the base class and make it virtual, or you need to do a type-safe down cast, using dynamic_cast. It is probably better to make the function a part of the interface, and have it available both in the base class and in the child class, but without more information it's hard to say. Generally speaking, though, the use of RTTI and dynamic_cast are indicative of poor design.
Why would you want to do this? If you're taking in an object of class base, you can't call a function of class child.
Your desires are contrary to the purpose of the data structures you're using.
You can do it with
child *child_object = dynamic_cast<child*>(object);
child_object -> dummyfunction();
but you shouldn't. Try designing your system properly instead.
In addition to using dynamic cast you can use static_cast with references:
base &b = base();
static_cast<child&>(b).dummyFunction();
What you required is downcasting.
you can acheive by making the dummyFunction as virtual in base class and then overriding this function in child class this solution would not require downcasting
otherwise you can use the method described in the below post but this is not safe to downcast
Downcasting Method
Suppose the function you want to call is
void f();
Make it virtual in Base class and override in Derived class and then call it from inside any member function of the Base class (except constructor!).
Sorry if this is a dupe, I cant find an answer quite right.
I want to call a function from a base class member, and have it resolve to the subclass version. I thought declaring it virtual would do it, but it isn't. Here's my approach:
class GUIWindow
{
public:
GUIWindow()
{
SetupCallbacks();
}
virtual void SetupCallbacks()
{
// This function always called
}
};
class GUIListbox : public GUIWindow
{
public:
void SetupCallbacks()
{
// This never called
}
};
GUIListbox lb; // GUIWindow::SetupCallbacks is called :(
What am I doing wrong?
Many thanks
Si
Never call a virtual function in the constructor.
When you call virtual functions during construction of some class C (i.e. while the constructor of C is active), the virtual mechanism works, but it works in restricted mode. The resolution of the virtual calls in the class hierarchy is limited by the class that is currently being constructed (C). This means that the virtual calls will resolve as if the class C is the "final" class in the hierarchy, as if it has no descendants.
The same is true for destructors.
In your example, you are calling a virtual function from constructor of class GUIWindow. As long as the constructor of GUIWindow is active, its virtual mechanism will work as if there are no other classes derived from GUIWindow. This mechanism will completely ignore the existence of GUIListbox class. This is why the resolution of virtual call "stops" at GUIWindow and calls GUIWindow::SetupCallbacks, as if GUIListbox::SetupCallbacks doesn't exist.
You can read about in in C++ FAQ
http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.5
Your derived type is not constructed yet.
Class Cat : Animal
{
//...
};
When you create a create a Cat object the following happens:
Construct Animal
Construct Cat
When your object goes out of scope or gets destroyed via delete if on the heap, the following happens:
Destruct Cat
Destruct Animal
For this reason you should not call virtual functions in your constructor or destructor. You would even have a pure virtual function call if you did not have an implementation in your base class.
You are going to have to:
GUIListbox lb;
lb.SetupCallbacks();
The point of virtual is so that you can do things like:
GuiWindow *lb = new GuiListbox();
lb->SetupCallback();//Gets correctly resolved to GuiListBox's version
The problem is that you are trying to call the virtual function form the constructor. The base class constructor is called before the constructor of the derived class, so the "derived parts" of the object are not created yet when the base classes constructor runs.
The object will behave like an object of the base class type until the base classes constructor is finished and the derived classes constructor starts. This means that calls to virtual functions will not call implementations defined in the derived class, they will just execute the version from the base class.
Also see the C++ FAQ lite for more details and possible workarounds.
The quick answer is that you may have to declare a constructor in GUIListbox which calls SetupCallbacks. The reason is more complicated: because GUIListbox doesn't declare a constructor, when you declare an object of that type the GUIWindow constructor is called. When the GUIWindow constructor is running, the object isn't a GUIListbox yet. From the compiler's perspective, it only becomes a GUIListbox once the (empty) constructor for that class starts. So when the first constructor runs, the methods from GUIWindow are called. IOWs, this doesn't work, and will never work in C++ the way that you want it to.
Here's a reference describing this pitfall in detail: http://www.artima.com/cppsource/nevercall.html.
And here's an explanation from my favorite C++ resource: http://yosefk.com/c++fqa/inheritance-mother.html#fqa-23.5