たとえば、次のことを考慮してください。
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
、参照渡しの場合はどうなりますか?
たとえば、次のことを考慮してください。
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
、参照渡しの場合はどうなりますか?
あなたは値渡しをしているので、タイプ Base の新しいオブジェクトを作成し、それにコピー代入を行っています..
非常に悪いことに、スライスが発生します..ステージが保持されず、推奨されません. http://en.wikipedia.org/wiki/Object_slicing
参照渡しまたは const 参照渡しのいずれかを行うと、いずれにせよより優れた高速な処理が可能になります。
bar(const Base& b)
またはオブジェクトへのポインターを渡すと、状態が保持されます。バー (ベース * b);
これは、これを処理する正しい方法です。
あなたの例で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()