例如,考虑:
class Deriv : public Base {...};
...
bar(Deriv d);
bar(Base b);
foo(Base b) {bar(b);}
...
Deriv x;
foo(x); // does x get treated as Base for the bar() call
// or retain its Deriv type?
如果foo
通过引用传递了该怎么办?
答案 0 :(得分:6)
您正在按值传递,因此您正在创建一个Base类型的新对象,并为其分配一个副本。
非常糟糕,你会经历切片......它不会保留它的阶段而不建议。 http://en.wikipedia.org/wiki/Object_slicing
通过引用或const引用传递,无论如何更好更快:
bar(const Base& b)
或传递指向该对象的指针,您将保留该状态。 bar(Base * b);
这将是处理此问题的正确方法。
答案 1 :(得分:3)
在您的示例中,x
将是Base
,这是因为您在调用函数时正在创建新的Base
对象。也就是说,在函数调用中,调用Base
的构造函数,创建从参数(Base
)b
子对象复制的x
Base
(称为对象切片)。它没有被视为作为Base
,它会创建一个新的Base
但是,如果您将参数视为Base &
,则会将其视为Derived
,请考虑以下代码:
#include <iostream>
class Base {
public:
virtual void func() const {
std::cout << "Base::Func()" << std::endl;
}
};
class Derived : public Base {
public:
virtual void func() const {
std::cout << "Derived::Func()" << std::endl;
}
};
int do_func_value(Base b){
b.func(); // will call Base::func
}
int do_func_ref(const Base & b){
b.func(); // will call whatever b's actual type is ::func
}
int main(void){
Derived d;
do_func_value(d);
do_func_ref(d);
return 0;
}
此输出:
Base::Func()
Derived::Func()