繁体   English   中英

通过对基类的引用调用虚函数

[英]Calling virtual functions through a reference to the base class

当我运行它时,此代码拒绝将适当的消息打印到控制台。 使用指针而不是引用似乎有效(-> 而不是 .)。 我是 OOP 的新手,如果你觉得这很荒谬,请原谅我。

#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
}
instrument &pi = i;

在这里,您让pi指代instrument对象i

pi = p;

在这里,您将piano对象p分配给pi引用的对象。 参考pi不会反弹到piano对象。 它仍然引用与以前相同的instrument对象。 只是使用隐式生成的默认赋值运算符为其分配了不同的内容。 (在这种情况下,赋值不起作用,但将派生类型分配给基类型通常会导致对象切片。)当您调用pi.play() ,引用仍然引用instrument对象,并且instrument::play是执行。

关键是,虽然你可以得到一个指向不同类型的不同对象的指针,但你不能用引用做同样的事情。 它总是指向同一个对象。 您可以通过使用多个引用来修复您的代码:

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

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

instrument &pd = d;
pd.play();  // dum, dum
int main ()
{ 
    instrument i,*pi;
    piano p;
    drum d; 
    pi= &i; 
    pi->play(); // - 
    pi = &p; 
    pi->play(); // pling
    pi = &d; 
    pi->play(); // dum, dum 
}

采用:

virtual void play() = 0;

代替:

virtual void play(){}

它可以防止创建冗余对象的可能性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM