gpt4 book ai didi

c++ - 为什么这个虚方法返回真?

转载 作者:太空狗 更新时间:2023-10-29 23:35:42 26 4
gpt4 key购买 nike

在学习 C++ 中的多态性教程时,我发现一些代码在调用未重写的虚拟方法时表现异常。以下是类(class):

// classes.cpp

namespace Classes
{
class C
{
public:
virtual bool has_eyesight()
{
return false;
}
} c;

class See : public C
{
public:
bool has_eyesight() override
{
return true;
}
} si;
}

这里是主要方法:

// file.cpp

#include <iostream>
#include "classes.cpp"

using std::cout;
using std::endl;
using Classes::C;
using Classes::See;

int main()
{
See& si = Classes::si;

cout << si.has_eyesight() << endl;

C& c = si;

cout << c.has_eyesight() << endl;

c = Classes::c;

cout << c.has_eyesight() << endl;
}

这段代码在运行时会打印1 1 1 (true true true);如果 c.has_eyesight() 引用的是 C 而不是 See,它不应该返回 false 吗?

(如果这听起来很天真,请原谅我,我才刚刚开始学习 C++。)

最佳答案

让我们来看看你在这里做什么。

C& c = si;

c 现在是对 Classes::si 的引用,它是 See 的一个实例。所以它的 vtable 指向 See 的 vtable,has_eyesight() 将返回 true。

引用和指针之间的主要区别是您不能修改它的目标 - c 现在将始终指向 Classes::si,无论如何你做。意思是……

c = Classes::c;

这不会改变对 Classes::c 的引用。您不能修改引用。相反,它会调用 c 上的赋值运算符,因此现在您正在将 Classes::c 复制到 Classes::si 上。除非您重载 operator=,否则这将执行逐个成员的复制。它不会修改 vtable,因此 has_eyesight() 将继续返回 true。

如果你确实想让它指向别的东西,你将不得不使用一个指针:

See* si = &Classes::si;
cout << si->has_eyesight() << endl;
C* c = si;
cout << c->has_eyesight() << endl;
c = &Classes::c;
cout << c->has_eyesight() << endl;

试试这个。

关于c++ - 为什么这个虚方法返回真?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31485467/

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