在学习有关C ++中的多态性的教程时,我看到一些代码在调用非重写虚拟方法时似乎表现得很奇怪。这些是类:
// 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指向的vtable See
,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;
尝试这个。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句