2

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

   #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(); // ?

    }
4

2 回答 2

5

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

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

于 2012-04-26T01:12:12.320 回答
3
A obj3 = obj1; // Why it is different from obj2

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

A &obj2 = obj1;

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

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

于 2012-04-26T01:11:27.617 回答