请考虑以下代码:
class A {
public:
virtual ~A() { }
virtual void print() const {
std::cout << "In A" << std::endl;
}
};
class B : public A {
public:
B() { }
virtual ~B() { }
virtual void print() const {
std::cout << "In B" << std::endl;
}
};
void doSomething(A* a) {
a->print();
}
void doSomething(const A a) {
a.print();
}
int main()
{
A* a = new B();
doSomething(a);
doSomething(B());
return 0;
}
为什么输出:
In B
In A
但是当您将doSomething
更改为doSomething(const A& a)
时,它会输出:
In B
In B
答案 0 :(得分:10)
这称为切片。
按值传递A
时,只复制调用方对象的A
部分,即可生成本地副本。由于它既有静态和动态类型的A
,也就是所选择的print
的覆盖。
通过引用传递,该函数获取对动态类型B
的调用者对象的引用,以便选择覆盖。
使用抽象基类可以防止这样的混乱行为 - 它们不能直接实例化,因此不能通过值传递。