【问题标题】:Why must the base class object be a reference to call the derived virtual function?为什么基类对象必须是调用派生虚函数的引用?
【发布时间】:2012-04-26 01:09:02
【问题描述】:

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

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

    }

【问题讨论】:

  • 因为多态只适用于引用和指针。
  • “为什么 X 需要 Y?” “因为 Y 是 X 的要求。”不是很有帮助的评论

标签: c++ class reference overriding virtual


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:
    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 &amp;obj2 只是为其他已经存在的东西创建一个引用/别名。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-16
      • 2017-01-20
      • 2017-11-03
      • 2020-06-22
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 2020-11-15
      相关资源
      最近更新 更多