//Parent.h
class Parent
{
public:
virtual void foo() = 0;
};
//Child.h
class Child : public Parent
{
public:
virtual void foo(){cout << "inside function foo()" << endl;}
virtual void bar(){cout << "inside function bar()" << endl;};
};
int main( int argc, char** argv ){
Parent* pa = new Child;
pa->foo();
pa->bar(); //Error, class Parent have no member bar
return 0;
}
How do i avoid this error other than add those function to the Parent class
You can declare your pointer as Child type. You will still be able to pass it to function expecting a Parent pointer.
Other solution involves using dynamic_cast<Child>(pa) although this is often seen as bad design to need this because it defeats what polymorphism is supposed to accomplish.
You can use static or dynamic_cast. Example with dynamic_cast:
if (Child* child = dynamic_cast<Child*>(pa))
child->bar();
You avoid this error by being more careful in your class design in the first place.
Yes, you can use dynamic_cast or static_cast to cast a Base pointer to a Derived pointer if the types are related, as they are here. But let's think about this.
Q: Why do you use polymorphism?
A: To provide different behaviour for similar operations, where the behaviour is selected at run-time.
Polymorphism is used to abstract away the implementation of an operation from the provision of that operation. All Shapes for example have a number of sides. How many sides depends on the actual shape, but we shouldn't have to know what kind of Shape something is in order to ask it how many sides it has. We should be able to just ask it.
Q: Why do you typically need to use dynamic_cast?
A: Because the base pointer doesn't provide the facilities you need.
If we shouldn't have to care what kind of Shape some object is in order to carry out the operations we need on it, then why would the Shape interface ever not provide whatever facilities we need?
This happens when we've made a mistake in designing something. Either Shape didn't have enough or the right kinds of facilities in it, or some particular Shape subclass is trying to do more than it should.
That's what you've done here. If it doesn't make sense for Parent to have a (public) bar() method on it, then it shouldn't make sense for Child to have it either. If it does make sense for Child to have a bar method on it, then Child isn't really a Parent, is it?
Maybe bar should be a method in some other class.
First we need to know why compiler is complaining !! You will never come to know the reason if anybody tell you the fix. First understand the reason.
You are getting the error during compilation. vTable and vPtr does not come into picture during early binding. It comes into picture in late binding. Base class does not have bar method, so compiler is complaining you that the method called by base class in unknown. So you need to typecast it to derived class pointer so that early binding gets passed. I hope my understand about the problem is correct. Correct me if I am wrong.
Related
I have a class hierarchy with lots of shared member functions in a base class, and also a large number of unique member functions in two derived classes:
class Scene {
public:
void Display();
void CreateDefaultShapes();
void AddShape(Shape myShape);
// lots more shared member functions
}
Class AnimatedScene : public Scene {
public:
void SetupAnimation();
void ChangeAnimationSpeed(float x, float y);
// lots of member functions unique to animation
}
Class ControllableScene : public Scene {
public:
void ConfigureControls();
void MoveCamera(float x, float y, float z);
void Rotate(float x, float y, float z);
// lots of member functions unique to a controllable scene
}
Not surprisingly, this doesn't work:
Scene myScene;
myScene.SetupAnimation();
What is the correct solution to this problem? Should I make all of the derived member functions virtual and add them to the base? Should I use a cast when calling SetupAnimation()? Is there a more clever design that solves this problem?
Note: I receive myScene from elsewhere and can't simply declare it as AnimatedScene when I instantiate it.
Edit: I've added a couple more member functions to illustrate the point. A small handful of initialization functions definitely lend themselves to simply using virtual.
You can cast it, preferably using static_cast. The least preferable option. If you are casting things, it usually means your design needs more thought
If you have a particular function/class that needs one or the other, declare the input as the type you need, which more accurately communicates the requirements of the function or class
If the function needs to be generic, and those methods don't require any input, then you could define a virtual method in the parent class, say init, which in the derived classes call the correct methods to set up the instance.
I have a similar problem in my compiler project, where the AST (Abstract Syntax Tree) is constructed from the statements, so while(x != 0) { if (a == b) x = 0; } would construct a whileAST with a binaryExpr inside it, then a blockAST with the ifAST, and so on. Each of these have some common properties, and a lot of things that only apply when you actually do something specific to that part. Most of the time, that is solved by calling a generic (virtual) member function.
However, SOMETIMES you need to do very specific things. There are two ways to do that:
use dynamic_cast (or typeid + reinterpret_cast or static cast).
Set up dozens of virtual member functions, which mostly are completely useless (doesn't do anything or return an "can't do that" indication of some sort)
In my case, I choose the first one. It shouldn't be the common case, but sometimes it is indeed the right thing to do.
So in this case, you'd do something like:
AnimatedScene *animScene = dynamic_cast<AnimatedScene*>(&scene);
if (!animScene)
{
... do something else, since it's not an AnimatedScene ...
}
animScene->SetupAnimation();
I am not yet able to comment, which is what I really wanted to do, but I am also interested in figuring this out as well.
A few months ago I had a similar problem. What I can tell you is that you can use typeid operator to figure out what type the object is, like so:
int main()
{
scene* ptr = new AnimatedScene();
if (typeid(*ptr) == typeid(AnimatedScene))
{
cout<<"ptr is indeed a animatedScene"<<endl;
AnimatedScene* ptr2 = (AnimatedScene*)(ptr);
ptr2->SetupAnimation();
}
else
{
cout<<"not a animatedscene!!!"<<endl;
}
}
This works, you'll then be able to use ptr2 to access the animatedScene's unique members.
Notice the use of pointers, you can't use the objects directly, due to something called "object slicing" when playing with polymorphism: https://en.wikipedia.org/wiki/Object_slicing
Like you I have heard something about the use of typeid and thus, casting being a bad idea, but as to why, I cannot tell you. I am hoping to have a more experienced programmer explain it.
What I can tell you is that this works without problems in this simple example, you've avoided the problem of declaring meaningless virtual functions in the basetype.
Edit: It's amazing how often I forget to use google: Why is usage of the typeid keyword bad design?
If I understand mr Bolas correctly, typeid incentivizes bad coding practices. However, in your example you want to access a subtypes non-virtual function. As far as I know, there is no way of doing that without checking type at compiletime, ie typeid.
If such problem arises with your hierarchy that proves that hierarchy was too generalized. You might want to implement interfaces pattern, if class have certain functionality, it would inherit an interface that defines that functionality.
Proven that dogs are animals, do all animal but dogs fail to bark, or do only dogs bark?
The first approach lead to a class animal failing all the verses of the entire zoo, implemented one-by one in each animal. And in particular class dog will override just bark().
In this approach animal becomes a sort of "god object" (knows everything), requiring to be constantly updated every time something new is introduced, and requiring It's entire "universe" to be re-created (recompile everything) after it.
The second approach requires first to check the animal is a dog (via dynamic cast) and then ask it to bark. (or check for cat before asking a mieow)
The trade-off will probably consist in understanding how frequent is the possibility you have to check a bark out of its context (not knowing which animal are you deal with), how to report a fail, and what to do in case of such fail.
In other words, the key driver is not the bark, but the context around it inside your program.
//Are you trying to do something like this?
class Scene{
public:
virtual void Display()=0; //Pure virtual func
};
class AnimatedScene : public Scene{
public:
void Display(){
std::cout<<"function Display() inside class AnimatedScene" <<std::endl;
}
};
class ControllableScene : public Scene{
public:
void Display(){
std::cout<<"function Display() inside class ControllableScene" <<std::endl;
}
};
int main(){
AnimatedScene as;
ControllableScene cs;
Scene *ex1 = &as;
Scene *ex2 = &cs;
ex1->Display();
ex2->Display();
return 0;
}
I have this parent class in C++
//ParentClass header file
public ParentClass{
public:
ParentClass();
virtual void someParentFunction();
private:
//other member variables and functions
};
//Functions implemented done in respective .cpp file
I extended this class so I have a child that looks like this
//ChildOneClass header file
public ChildOneClass : public ParentClass{
public:
//Constructors and other functions
private:
//Other members
};
//Functions implemented in respective .cpp file
Example declaration:
//Dynamically create one ChildOneClass object
ChildOneClass * c = new ChildOneClass();
//I know this is never done, but for example purposes i just did this
void * v = c;
I know if you have a pointer that points to the object you can do both:
((ParentClass *) v)->someParentFunction();
or:
((ChildOneClass *) v)->someParentFunction();
But which way is the correct way? Does it matter if I cast a pointer thats pointing to the subclass as a parent class? Sorry if this is confusing please give me some feedback if the question is confusing. I'll do my best to clarify
The only correct cast of a void* to a class pointer is the cast to the original class pointer type passed to the void*. Anything else may lead to unexpected results (eg.: having virtual or multiple inheritance)
NOTE: This answer addresses a later revision of the original question, which has since been reverted. For an answer to the original and current revision of the question, please see Dieter Lucking's answer.
If you want to call someParentFunction() on a class which may have a derived class which contains that function, you'll want to use dynamic_cast to the most base class with which that call is valid:
GrandParentClass *g = ...;
if (ParentClass* pc = dynamic_cast<ParentClass*>(g)) {
// ok, it's a ParentClass, this is safe
pc->someParentFunction();
}
else {
// not a ParentClass, do something else, log an error, throw, etc.
}
There's no reason to cast all the way down to ChildOneClass, since you would miss all the types that are ParentClass but are not ChildOneClass. This covers all the valid subsets. Note that GrandParentClass would need to be polymorphic in order for this to work (e.g. GrandParentClass has a virtual member function).
When you are creating polymorphic hierarchies you should be thinking in terms of interfaces. Ideally you should never need to cast. However in some cases it is necessary.
When you cast it should be to the specific interface that you need. So if you need to process objects of the derived type cast to the derived type. If you need to process objects of the base type cast to the base type.
Your design should make it obvious what interface is being dealt with at which point in the system.
If you are casting a lot (or even at all) it could be a symptom of poor design.
I'm learning C++ now and I read a lot of materials about using superclass's pointer to point to a subclass' object, especially in the case of (pure) virtual classes. Since I don't have a lot of experience, could anyone help me to understand why we need to do that? Thanks a lot!
You don't need to. You can use a pointer to the derived type if that's what you really want.
The Liskov substitution principle says that we should always be able to use a derived type wherever the base type is expected. The idea is that a derived type should be no more restrictive than its base class. That way, the derived really is-a base type, and can be used wherever the base type would be used. The base type defines the interface and the derived type should meet that same interface. The derived type can augment the interface, if it likes.
The type of pointer that your function should take depends on exactly what you want to be able to accept. If you have a hierarchy with two Widgets, Button and List, for example, then if your function is happy to take any kind of Widget, it should take a Widget*. If the function specifically requires a Button, however, it should take a Button*. The reason for this is that the function probably requires some functionality that only the Button can provide.
When a member function is called through a pointer and the compiler sees that that function is virtual, the compiler ensures that the dynamic type of the object is used to determine which function to call. That is, imagine you have a Widget* parameter but actually pass a pointer to a Button object. The static type of the object is Widget (if the compiler were to only look at the parameter type), but its dynamic type is Button. If you call widget->draw(), where draw is a virtual function, it will see that the dynamic type is Button and ensure that Button::draw is called.
However, I don't recommend using raw pointers in general, so prefer references (Widget&) or smart pointers if you can.
Here's an example:
struct base { virtual void do_stuff(); = 0 };
struct specialization1: base {
void do_stuff() override { std::cout << "doing concrete stuff"; }
};
Consider that you have client code that wants to call do_stuff.
First implementation (this is how not to do it):
void client_do_stuff( specialization1& s ) { s.do_stuff(); }
This function works. If you decide (four months from now) to add to your code base:
struct specialization2: base {
void do_stuff() override { std::cout << "doing other concrete stuff"; }
};
You may want to call void client_do_stuff for an instance of specialization2. You could duplicate client_do_stuff with a specialization2 reference, but that is code duplication and unnecessary.
A better solution would be to change client_do_stuff to take a reference to the base class, and use the same implementation with both specializations.
Second implementation:
void client_do_stuff( base& b ) { b.do_stuff(); }
client code:
specialization1 s1;
specialization2 s2;
client_do_stuff(s1); // works
client_do_stuff(s2); // works
This implementation of client_do_stuff is implemented in terms of the public interface of the base class, instead of a specialization. This makes the function "future-proof" (the principle is sometimes called "program to an interface, not an implementation").
The idea is as follows: An object has the following interface (the pure virtual class). I will hand a concrete object to your code, which adheres to this interface, but the internal details of said object I will keep to myself (encapsulation). Thus your code can make no assumptions on the precise size etc. of the object. Therefore when compiling your code, you have to use pointers or references when manipulating the object.
I was studying Virtual Functions and Pointers. Below code made me to think about, why does one need Virtual Function when we can type cast base class pointer the way we want?
class baseclass {
public:
void show() {
cout << "In Base\n";
}
};
class derivedclass1 : public baseclass {
public:
void show() {
cout << "In Derived 1\n";
}
};
class derivedclass2 : public baseclass {
public:
void show() {
cout << "In Derived 2\n";
}
};
int main(void) {
baseclass * bptr[2];
bptr[0] = new derivedclass1;
bptr[1] = new derivedclass2;
((derivedclass1*) bptr)->show();
((derivedclass2*) bptr)->show();
delete bptr[0];
delete bptr[1];
return 0;
}
Gives same result if we use virtual in base class.
In Derived 1
In Derived 2
Am I missing something?
Your example appears to work, because there is no data, and no virtual methods, and no multiple inheritance. Try adding int value; to derivedclass1, const char *cstr; to derivedclass2, initialize these in corresponding constructors, and add printing these to corresponding show() methods.
You will see how show() will print garbage value (if you cast pointer to derivedclass1 when it is not) or crash (if you cast the pointer to derivedclass2 when class in fact is not of that type), or behave otherwise oddly.
C++ class member functions AKA methods are nothing more than functions, which take one hidden extra argument, this pointer, and they assume that it points to an object of right type. So when you have an object of type derivedclass1, but you cast a pointer to it to type derivedclass2, then what happens without virtual methods is this:
method of derivedclass2 gets called, because well, you explicitly said "this is a pointer to derivedclass2".
the method gets pointer to actual object, this. It thinks it points to actual instance of derivedclass2, which would have certain data members at certain offsets.
if the object actually is a derivedclass1, that memory contains something quite different. So if method thinks there is a char pointer, but in fact there isn't, then accessing the data it points to will probably access illegal address and crash.
If you instead use virtual methods, and have pointer to common base class, then when you call a method, compiler generates code to call the right method. It actually inserts code and data (using a table filled with virtual method pointers, usually called vtable, one per class, and pointer to it, one per object/instance) with which it knows to call the right method. So when ever you call a virtual method, it's not a direct call, but instead the object has extra pointer to the vtable of the real class, which tells what method should really be called for that object.
In summary, type casts are in no way an alternative to virtual methods. And, as a side note, every type cast is a place to ask "Why is this cast here? Is there some fundamental problem with this software, if it needs a cast here?". Legitimate use cases for type casts are quite rare indeed, especially with OOP objects. Also, never use C-style type casts with object pointers, use static_cast and dynamic_cast if you really need to cast.
If you use virtual functions, your code calling the function doesn't need to know about the actual class of the object. You'd just call the function blindly and correct function would be executed. This is the basis of polymorphism.
Type-casting is always risky and can cause run-time errors in large programs.
Your code should be open for extension but closed for modifications.
Hope this helps.
You need virtual functions where you don't know the derived type until run-time (e.g. when it depends on user input).
In your example, you have hard-coded casts to derivedclass2 and derivedclass1. Now what would you do here?
void f(baseclass * bptr)
{
// call the right show() function
}
Perhaps your confusion stems from the fact that you've not yet encountered a situation where virtual functions were actually useful. When you always know exactly at compile-time the concrete type you are operating on, then you don't need virtual functions at all.
Two other problems in your example code:
Use of C-style cast instead of C++-style dynamic_cast (of course, you usually don't need to cast anyway when you use virtual functons for the problem they are designed to solve).
Treating arrays polymorphically. See Item 3 in Scott Meyer's More Effective C++ book ("Never treat arrays polymorphically").
So this is probably a weird question, but I have a reasonably good reason for asking.
The gist of my question is, given an example with two levels of derivation on a class hierarchy:
Main Base Class:
class Animal
{
virtual void Draw() = 0;
};
Derived Class:
class Dog : public Animal
{
virtual void Draw()
{
// draw a generic dog icon or something...
}
};
Further Derivation:
class Corgi : public Dog
{
virtual void Draw()
{
// draw a corgi icon...
}
};
Now, I'd love to be able to, from within the Corgi class, permanently downcast the 'this' pointer to a Dog pointer and then pass it off somewhere else as an Animal. This other place will then be able to call the Draw function and get the Dog method, not the virtual Corgi method. I know this is strange, but again, I have a vaguely legitimate reason for wanting to do it.
I've tried all the different casting operators and haven't had any luck, but maybe there is a consistent way of pulling this off? In the past I've caused myself trouble by not properly using dynamic_cast which resulted in a similar state for a pointer. Perhaps this time I can use that to my advantage?
Edit:
Perhaps the above example doesn't illustrate clearly the what I'm trying to achieve, so I'll elaborate with my real goal.
I'm trying to achieve a shorthand for registering base class implementations that link into a scripting system I've been using for a while. The scripting system relies on a base class IScriptContext to facilitate access to real-code functions and member variable access. Internally base classes register their member function addresses and member variable addresses which are later dispatched/accessed through lookup tables. I'm in the process of adding proper support for class derivation hierarchies to the scripting system, and I figured being able to isolate the base class versions of these interfaces would help save time and make the whole process cleaner for me when it comes time to register available base classes with the script interpreter. There are other ways to achieve this, such as registering class specific function pointers for each required method for each available base class (e.g. this->Dog::CallFunction, this->Dog::SetMember, this->Dog::GetMember.) However, I figured using an interface would allow me to modify things a bit easier down the road if I ever needed to.
I hope all of that makes some kind of sense.
Thanks!
You have a Corgi object. You can:
Treat it as a Dog object everywhere by using the Dog:: qualifier to all calls (e.g. ptr->Dog::draw();). This loses you virtual dispatch, and is almost certainly not what you want from how your question reads.
Actually construct a new Dog object from your Corgi. Just do this with a normal static_cast as you'd convert any other type or let implicit conversion take over (e.g. Corgi c; Dog d(c);).
These are the options available to you. To want to retain a Corgi but automatically pretend everywhere that it's a Dog is neither reasonable nor legitimate, so the language does not provide for it.
Let me start off by saying your design looks faulty.
You can however explicitly say which function in a hierarchy you want to call:
Corgi* corgi = new Corgi;
corgi->Dog::draw();
This will call the draw method from Dog, not from Corgi. (I hope I understood correctly what you're asking).
Tomalak has already outlined two of the main choices available to you:
use qualified calls, or
construct a Dog as a Dog copy of your Corgi.
In addition to these, you can
use a simple wrapper
e.g.
class LooksLikeDog
: public Dog
{
private:
Dog* realObject_;
LooksLikeDog( LooksLikeDog const& ); // No such.
LooksLikeDog& operator=( LooksLikeDog const& ); // No such.
public:
LooksLikeDog( Dog& other )
: realObject_( &other )
{}
// Just for exposition: not implementing this does the same.
virtual void draw() override { Dog::draw(); }
// Example of other method that may need to be implemented:
virtual void bark() override { realObject_->bark(); }
};
But the best solution is most probably to fix your design. ;-)
Implement Corgi draw function and call your parent's implementation:
virtual void Corgi::Draw()
{
Dog::draw();
}