为什么基类对象必须是调用派生虚函数的引用?

时间:2012-04-26 01:09:02

标签: c++ class reference override virtual

为什么基类对象必须是调用派生虚函数的引用?

   #include<iostream>
    using namespace std;

    class A {

    public:
        virtual void print() { cout << "Hello 1" << endl; }

    };

    class B : public A {

    public:
        int x;
        void print() { cout << "Hello " << x << endl; }

    };

    void main(){

        B obj1;
        A &obj2 = obj1;
        A obj3 = obj1; // Why it is different from obj2

        obj1.x = 2;

        obj1.print();
        obj2.print();
        obj3.print(); // ?

    }

2 个答案:

答案 0 :(得分:5)

当您将派生对象分配给基础变量时,它会将“sliced”转换为基类的实例;它不再是派生的实例。这是必要的,因为基本变量只有足够的空间保留给基类的实例;派生类的实例及其附加数据将不适合。

使用引用时,不必将对象复制到较小的空间中,因此不会发生切片。

答案 1 :(得分:3)

A obj3 = obj1; // Why it is different from obj2

通过复制构建obj3。在这种情况下,obj1向上转换为A类型,其中obj3由obj1的“A”参数构成。这种现象称为slicing

A &obj2 = obj1;

此行将引用obj2绑定到obj1的实例。你已经通过将obj2指向它来将obj1提升为“A”。请记住,在C ++中,引用实际上只是一个别名。您刚刚给obj1一个不同的名称,该名称绑定到基类类型。

所以A obj3在堆栈上分配和构造一个全新的对象,而A &obj2只为已经存在的其他东西创建一个引用/别名。