子类到基类转换问题

时间:2013-08-03 18:07:21

标签: c++ virtual

我已经使用虚拟打印功能声明了一个Super Class,而Child类继承了Super类。我创建了一个Child Class实例,并以两种不同的方式分配给Super Class。

#include <iostream>

using namespace std;

class Super
{
public:
    Super(){}
    virtual void print()
    {
    cout << "Super class is printing " << endl;
    }
};

class Child: public Super
{
public:
    Child(){}
    void print()
    {
        cout << "Child class printing" << endl;
    }
};

int main()
{
    Child c;
    Super s = c;
    Super &ss = c;
    s.print(); //prints "Super Class is printing
    ss.print(); //prints "Child Class is printing
    return 0;
}

为什么我们从这两个打印调用中得不到相同的输出?添加引用如何改变行为?

2 个答案:

答案 0 :(得分:2)

s的动态静态类型为Super,但c的分配会从Super内部创建c子对象的副本{1}}和s始终表现为Super

但是,ss的静态类型为Super,但其动态类型取决于其初始化,在本例中为Child,因此虚拟调度的行为相应。

这种现象称为"object slicing"

答案 1 :(得分:1)

对象切片问题:

如果您使用超类并为其分配子类的值,则只会复制属于超类的成员(默认赋值运算符行为)。

请考虑以下事项:

#include <iostream>

using namespace std;

class Super {
public:
   int a;
   Super(): a(0) { }
   Super(int _a): a(_a) { }
   virtual void dump() {
        cout << "A is : " << a << std::endl;
   }
};

class Child: public Super {
public: 
   int b;

   Child(int _a, int _b): b(_b), Super(_a) { } 
   virtual void dump() {
        Super::dump();
        cout << "B is : " << b << std::endl;
   }

};

int main() {
    Child c(5, 10);
    Super s;
    s.dump();  // A is 0
    s = c;
    s.dump();  // A is 5 (but there is no B in s 
               // so calling Child::dump would be nonsensical
}

因此,当您将子值分配给父级时,您可以看到调用子级dump是没有意义的;因为父上下文中没有“b”。

请注意以下声明:         c = s;

是非语义的,因为虽然parentage是确定性的(Child是Super的类型,因此隐式运算符Super& Super::operator=(const Super&)适用于派生的Child类,反之则不正确;即{{1}在Child& Child::operator=(const Child&)

的上下文中没有意义

参考问题

好的,因为理解引用变量是什么造成的混乱。引用变量是初始化的任何内容的同义词。您可以使用与原始参数完全相同的参考变量。

在你的情况下:

Super

相同
   ss.print(); 

” 要更明确地看到这一点,请考虑以下代码段:

   c.print();