我正在学习虚函数,我对下面程序的结果感到非常困惑我希望a1.virFun(b1)和b1.virFun(b1)都应该返回"hello from B",但程序返回"hello from A“。这与我的理解相反。你能解释一下为什么b1.sayHello()没有被调用吗,即使我将b1作为参数传递,而b1.sayHello()是虚函数。
#include<iostream>
using namespace std;
class A
{
public:
virtual void sayHello();
void virFun(A obj);
};
class B : public A
{
public:
void virFun(A obj);
virtual void sayHello();
};
void A::sayHello()
{
cout << "hello from A" << endl;
}
void B::sayHello()
{
cout <<"hello from B" << endl;
}
void A::virFun(A obj)
{
obj.sayHello();
}
void B::virFun(A obj)
{
obj.sayHello();
}
int main()
{
A a1;
B b1;
a1.virFun(b1);
b1.virFun(b1);
return 0;
}发布于 2012-10-12 21:45:33
通过值使virFun接受引用,而不是A对象:
void A::virFun(A& obj) { obj.sayHello(); }原因:如果按值获取
A,则参数将通过复制传递的值来初始化。如果你传递一个B,它会把它的'A‘部分复制到一个参数类型(A)的新变量中--这就是所谓的。该参数将不再是一个B实例,因此它将表现为一个A实例。
不需要覆盖类B中的virFun,因为它在两种情况下都使用参数obj
实际上,virFun可以是一个静态函数。它的名字令人困惑,因为它甚至不是一个virFun (虚函数)-它是一个使用虚函数的常规函数。
#include<iostream>
using namespace std;
struct A { virtual void sayHello() { cout << "hello from A" << endl; } };
struct B : A { /*virtual*/ void sayHello() { cout << "hello from B" << endl; } };
static void virFun(A& obj)
{
obj.sayHello();
}
int main()
{
A a1;
B b1;
virFun(a1);
virFun(b1);
}在http://liveworkspace.org/code/1624496ced29eb4683f5b19072f72f60上观看现场直播
hello from A
hello from B发布于 2012-10-12 21:46:05
void virFun(A obj);要使虚函数工作,您需要通过引用或指针传递对象,以确保始终使用原始对象。
void virFun(const A &obj);
void virFun(const A *obj);否则,virFun()将收到您的对象的副本,这最终会对其执行"slicing"操作并丢失派生类的信息。该副本有A的vtable,并且缺少B的额外字段。这通常是一场灾难。
一般来说,使用T&或const T&而不是普通的T传递对象。除了切片问题,它的效率也更高。
https://stackoverflow.com/questions/12860409
复制相似问题