Call child version of function instead of parents?

Ok, so I got two classes.

class a{ public: a(){}; void print(){cout << "hello"}; } class b : public a{ public: void print(){cout << "hello world";} } 

And an array of parents with a child

 a blah[10]; blah[5] = b(); 

What I call the seal, and I want him to say hello to the world.

 blah[5].print(); 

But he calls the parent. How to fix it?

+8
c ++ override inheritance virtual
source share
4 answers

This can be fixed by declaring a virtual, a la function:

 class a{ public: virtual void print(){ cout << "hello"; } } class b : public a{ public: virtual void print() { cout << "hello world"; } } 

This is how polymorphism is implemented in C ++. More details here: http://en.wikipedia.org/wiki/Virtual_function

However, it should be noted that in your example, it will never call the child function, because you are using the values โ€‹โ€‹of objects, not pointers / references to objects. To fix this,

 a * blah[10]; blah[5] = new b(); 

Then:

 blah[5]->print(); 
+11
source share

What you are looking for is run-time polymorphism, which means that the object takes "many forms" (i.e. a or b) and acts accordingly as the program launches. In C ++, you do this by creating a virtual function in the base class a :

 virtual void print() {cout << "hello"}; 

Then you need to save the elements by pointer or link, and, as a rule, derived classes can introduce new data members and need more memory - this is normal for creating objects on the heap with new :

 a* blah[10]; blah[5] = new b(); 

Then you can call:

 blah[5]->print(); 

And he will choose b implementation of print() .

You should delete blah[5] later (and any other pointer to the memory returned by new ).

In practice, it is useful to use a container that can remove the objects that it contains when it is destroyed, due to the fact that it left the area or was deleted. std::vector<> is one such container. You can also use smart pointers to automate the deletion of objects a and b . This helps make the code correct if exceptions are thrown before executing delete , and you want your program to continue to run without memory leak. The acceleration library is the easiest / best place to implement a smart pointer. Together:

 #include <vector> #include <boost/shared_ptr.hpp> std::vector<boost::shared_pointer<a> > blah(10); blah[5] = new b(); 

(It is more natural to use vectors with push_back() , since it automatically generates a vector so that it fits all the elements you added with the new general accessibility by calling vector::size() .)

+2
source share

This is because you told the compiler that your instance is of type a . This is in an array of a objects, right? So this is type a !

Of course, you want the method in b overwrite the file in a , despite having a reference to the parent type. You can get this behavior using the virutal keyword in a function declaration in the parent class.

 virtual void print(){cout << "hello"}; 

Why does it work?

Because when you throw your object into the parent class, you introduce ambiguity. When this print() object is called, how should we handle it? It is of type b , but the link is of type a , so the environment code can expect it to behave like a , not b !

To disambiguate, the virtual keyword is entered. virtual functions are always overridden if an object has a child class containing a method with the same signature.

Hooray!

0
source share

Declare a::print() as virtual and use a pointer / link to call the print() function. When you execute blah[5] = b() , it performs slicing of objects. You cannot call a virtual function with an object.

-one
source share

All Articles