引用变量和继承

reference variables and inheritence

本文关键字:继承 变量 引用      更新时间:2023-10-16

以下代码:

#include <stdio.h>
class Parent
{
public:
    virtual void func() {printf("Parentn");}
};
class Child1 : public Parent
{
    virtual void func() {printf("Child1n");}
};
class Child2 : public Parent
{
    virtual void func() {printf("Child2n");}
};
int main(int argc, char* argv[])
{
    Parent & obj = Child1();
    obj.func();
    obj = Child2();
    obj.func();
    return 0;
}

产生以下结果:

expected: Child1 Child2.
actual: Child1 Child1. 

(编译于VS2010(

我猜 vptr 不会因分配而改变。有没有办法让它被重新创建(除了使用指向父级的指针并使用 new 分配给它(?

谢谢

您正在调用 obj 上的默认赋值运算符,该运算符的类型仍然是 Child1,参数类型为 Child2。对象本身仍为 Child1 类型。您可以通过在所有 3 个类上实现 operator = 并在其中插入 print 语句来验证这一点。

Parent & obj = Child1();

创建对类型 Child1 的对象的引用。这就像在说

Child1 c1;
Parent& obj = c1;

obj现在只是c1的不同名称,它是一个类型为 Child1 的对象。

obj = Child2();
obj.func();

现在,这就像在说

c1 = Child2();
c1.func();

所以你看,你仍然在 Child1 类型的对象上调用 func

C++中的两个基本属性:对象,一旦创建,永远不会更改其类型,并且引用一旦初始化,将始终引用同一对象。

这里发生的事情是你正在调用提供的编译器Parent的非虚拟operator=,这几乎肯定不是你想要的。 然而,更一般地说,赋值和继承不会协同工作良好(正是因为您无法更改对象(;大多数时候,在使用继承时,你应该禁止赋值(例如,通过从boost::noncopyable继承(。 它可以为多态类实现值语义,使用信件/信封成语,但这是一个沉重的解决方案,很少适当。

(我可以补充一点,您的代码无法使用C++编译器进行编译。 你是使用临时初始化对非常量的引用,这不是法律C++。 允许这是一个Microsoft扩展。

引用不能重新拔插 - 它们在其整个生命周期中引用同一对象。如果你想要一些可以改变它所引用的对象的东西,那么你需要使用[智能]指针而不是引用。

您在这里所做的是通过将Child2实例分配给Child1的实例来对其进行切片。

您正在执行的操作应该会在编译中出错。不能将临时变量(由 Child2() 创建(分配给引用变量。你必须在 Child2 之前创建一个实例,并将该变量分配给敬畏。