Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling virtual functions through a reference to the base class

This code refuses to print the appropriate messages to the console when I run it. Using pointers instead of references seems to work (-> instead of .). I am new to OOP so forgive me if you find this ridiculous.

#include <iostream>

using namespace std;

class instrument {
public:
    virtual void play(){}
};

class drum : public instrument {
public:
    void play(){
        cout << "dum, dum" << endl;
    }
};

class piano : public instrument {
public:
    void play(){
        cout << "pling" << endl;
    }
};

int main (){
    instrument i;
    piano p;
    drum d;

    instrument &pi = i;
    pi.play();  // -

    pi = p;
    pi.play();  // pling

    pi = d;
    pi.play();  // dum, dum
}
like image 635
Venom Avatar asked Apr 21 '13 19:04

Venom


People also ask

How do you call a virtual function through a base class reference?

A virtual function is a member function that you expect to be redefined in derived classes. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function.

Can virtual function be defined in base class?

Rules for Virtual Functions Virtual functions should be accessed using pointer or reference of base class type to achieve runtime polymorphism. The prototype of virtual functions should be the same in the base as well as derived class. They are always defined in the base class and overridden in a derived class.

How do you call base class virtual method from derived class in C++?

A virtual function is a member function of a base class that is overridden by a derived class. When you use a pointer or a reference to the base class to refer to a derived class object, you can call a virtual function for that object and have it run the derived class's version of the function.

Can virtual function be inherited in C++?

Of course you can do it. Virtual method is optional to override so it doesn't matter that you declare it in class A or B.


2 Answers

int main ()
{ 
    instrument i,*pi;
    piano p;
    drum d; 
    pi= &i; 
    pi->play(); // - 
    pi = &p; 
    pi->play(); // pling
    pi = &d; 
    pi->play(); // dum, dum 
}
like image 90
Hawk amore Avatar answered Oct 09 '22 20:10

Hawk amore


instrument &pi = i;

Here you make pi refer to the instrument object i.

pi = p;

Here you are assigning the piano object p to the object referred to by pi. The reference pi is not rebound to the piano object. It still refers to the same instrument object as before. It's just that different contents have been assigned to it using the implicitly generated default assignment operator. (In this case, the assignment has no effect, but assigning a derived type to a base type usually results in object slicing.) When you call pi.play(), the reference still refers to an instrument object and instrument::play is executed.

The point is, while you can get a pointer to point at a different object of a different type, you can't do the same with a reference. It always points at the same object. You could fix your code by using multiple references:

instrument &pi = i;
pi.play();  // -

instrument &pp = p;
pp.play();  // pling

instrument &pd = d;
pd.play();  // dum, dum
like image 44
Joseph Mansfield Avatar answered Oct 09 '22 20:10

Joseph Mansfield