提问者:小点点

重写的函数在基类中没有反映,这是正常的行为吗? [副本]


给定以下代码:

class Base {
public:
    virtual void Test() {
        cout << "Not Overridden" << endl;
    }
};

class Derived : public Base {
public:
    void Test() override {
        cout << "Overridden" << endl;
    }
};

int main() {
    Base o = Derived();
    o.Test();
    return 0;
}

像我这样有Java背景的人希望编译器输出overridded,但令人惊讶的是,输出结果恰恰相反。 如果这是一种正常的行为,那么在C++中继承又有什么意义呢? 不然,我错过了什么?


共2个答案

匿名用户

是的,这是正常的行为,多态性只适用于指针和引用。

int main() {
    Base* o = new Derived();
    o->Test();
    return 0;
}

int main() {
    Derived d;
    Base& o = d;
    o.Test();
    return 0;
}

输出:

Overridden

网站上的一些线程解释了为什么会这样,就像这个。

您拥有它的方式导致对象切片。

您还需要向基类添加一个虚拟析构函数。

匿名用户

Base o = Derived();

上面的o是一个对象--一个对象--而不是一个派生对象。 O对象是通过对象切片从派生对象创建的,但O仍然是对象。 这里没有动态分派,因此o.test()导致调用base::test()

相反,如果将O声明为引用您创建的派生对象的指针:

int main() {
    Base* o = Derived(); // o is a pointer
    o->Test();
    return 0;
}

在这种情况下,O是指向对象的指针--与对象相反--并且动态分派生效:即使O是指向对象的指针,它也绑定到派生对象,因此O->test()导致由于动态分派而导致这次调用派生::test()

类似地,如果o是对base的引用,而不是指针。