gpt4 book ai didi

c++ - 带有引用的多态性不符合预期

转载 作者:太空狗 更新时间:2023-10-29 20:57:58 25 4
gpt4 key购买 nike

据我了解,使用引用的多态性应该与使用指针的方式完全一样。

但是,请考虑以下示例:在使用指针时正确调度了对 doer() 的调用,但在使用引用时似乎在这两种情况下都调用了“B 版本”。

我无法弄清楚以下示例的行为方式的原因。为什么在使用引用时在这两种情况下都调用了“B 版本”

#include <iostream>

class B;
class C;

void doer(B *x) {
std::cout << "B version" << std::endl;
}

void doer(C *x) {
std::cout << "C version" << std::endl;
}

class A {
public:
virtual ~A() {}
virtual void doit() = 0;
};

class B: public A {
public:
virtual void doit() override {
doer(this);
}
};

class C: public A {
public:
virtual void doit() override {
doer(this);
}
};

int main() {
B b;
C c;

A *a = &b;
a->doit(); // B version gets called, OK
a = &c;
a->doit(); // C version is called, OK

A &d = b;
d.doit(); // B version is called, OK
d = c;
d.doit(); // B version is called again??
}

最佳答案

在这里你分配一个引用:

A &d = b;
d.doit(); // B version is called, OK

在这里你用c覆盖了d引用的对象(它不再是引用的定义):

d = c;
d.doit(); // B version is called again??

这是引用和指针之间的主要区别。引用就像一个常量指针,你只能在定义时赋值。之后,无论何时您使用引用,它都表示您引用的对象。

事实上,当您执行 d = c; 时,会发生一些切片。对象d实际上是一个B,但是调用了A的operator=,只复制了A的成员数据。

这里如何演示这个语句:

class A {
public:
...
A& operator= (A a) {
cout << "A::operator=" << endl; // just to show what happens when d=c is called
return *this;
}
};
class B : public A {
public:
int x; // add some variables for B
virtual void doit() override {
cout << "B::doit() " << x << endl;
doer(this);
}
};
class C : public A {
public:
int a,b; // add aditional variables for C
virtual void doit() override {
cout << "C::doit() " << a << ","<<b << endl;
doer(this);
}
};
...
b.x = 123; // put some class specific variables in C
c.a = 222; c.b = 333; // put some class specific variables in C
A &d = b; // assignement of the reference. d reffers to a b object
d.doit(); // B version is called, OK
d = c; // but an A object is copied (so only A subobject of c is taken
// to overwrite A subobject of d)
d.doit(); // B version is called becaus again?? => yes !! because it's still a B
// And you see that the B part of the object is left intact by A::operator=
cout << typeid(d).name() << endl;
// remember at this point that d still refers to b !

关于c++ - 带有引用的多态性不符合预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28798071/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com