C++ 按值传递的切割问题(Slicing Problem)
C++ 的函数传参一般会建议避免使用按值传递的方式,除了按值传递的拷贝开销外,还有个原因就是按值值传递会导致切割问题:如果函数参数使用按值传递的方式,并且参数类型是一个类型的基类,调用时候传递继承类对象的时候,这个对象在拷贝的时候会被切割,也即继承类覆盖基类的部分被切割掉了,换句话说,就是拷贝的时候只拷贝了继承类的基类部分。例如:
#include <iostream>
class Base {
public:
virtual void foo() {
std::cout << "Base foo" << std::endl;
}
};
class Derived : public Base {
public:
virtual void foo() {
std::cout << "Derived foo" << std::endl;
}
};
void func(Base b) {
b.foo();
}
int main() {
Derived d;
func(d);
return 0;
}
虽然给 func
传递的是 Derived
类型对象,但是 func
参数类型是 Base
类型,产生对象切割,func
中 b.foo
结果如下:
Base foo
如果将 func
参数改成指针或者引用的方式,不会有该问题。