1

たとえば、次のことを考慮してください。

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、参照渡しの場合はどうなりますか?

4

2 に答える 2

6

あなたは値渡しをしているので、タイプ Base の新しいオブジェクトを作成し、それにコピー代入を行っています..

非常に悪いことに、スライスが発生します..ステージが保持されず、推奨されません. http://en.wikipedia.org/wiki/Object_slicing

参照渡しまたは const 参照渡しのいずれかを行うと、いずれにせよより優れた高速な処理が可能になります。

bar(const Base& b)

またはオブジェクトへのポインターを渡すと、状態が保持されます。バー (ベース * b);

これは、これを処理する正しい方法です。

于 2013-05-16T23:15:05.053 に答える
3

あなたの例でxは、 になります。これは、関数を呼び出すときにBase新しいオブジェクトを作成しているためです。Baseつまり、関数呼び出しで、コンストラクターが呼び出され、引数の (の)サブオブジェクトからコピーされた がBase作成されます (オブジェクト スライスと呼ばれます)。として扱われるのではなく、新しいものを作成しますBase bxBaseBaseBase

ただし、引数を として受け取ると、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()
于 2013-05-16T23:14:40.280 に答える