2

スライスを正しく理解していれば、ポインターやスマートポインターでこれが発生する可能性はないと思います。たとえば、次の場合:

class A
{
int something;
};

class B : public A
{
int stuff;
int morestuff;
};

int main()
{
    std::shared_ptr<B> b(new B());
    std::shared_ptr<A> a;
    a = b;
}

私の理解では、「b」が指すオブジェクトに割り当てられたメモリのブロックは依然として同じであり、スマートポインター「a」に割り当てられても変更されません。

私の理解を確認または拒否するか、これに関連する落とし穴があればお知らせください。

4

2 に答える 2

6

スマートポインタは依然としてポインタであるため、このような割り当てによってスライスが発生することはありません。スライスは、ポインタではなく、値を処理する場合にのみ発生します。ただし、テンプレートはポイントするアイテム間の関係を認識しないため、BがAから派生していても、からshared_pointer<B>派生していないshared_pointer<A>ため、割り当ては(自動的に)そのような自動アップキャストを取得しません。ネイティブポインタを使用します。

編集:最後のポイントについて詳しく説明します。

スライスはポインタではなく値で行われるため、(AとBの定義が与えられた場合)次のようになります。

A ax = b;

は機能しますが、Bオブジェクトを「スライス」してAオブジェクトになります。ただし、アイテムのインスタンスを保持するある種のテンプレートがある場合は、次のようになります。

template <class T>
class holder { 
   T t_;
public:
   holder &operator=(T const &t) { 
       t_ = t;
       return *this;
   }
   holder &operator=(holder const &t) { t_ = t; return *this; }
};

ここで、ある値を別の値に割り当てようとすると、スライスが発生します。

holder<A> ha;
holder<B> hb;

A a;
B b;

ha = a;
hb = b;
ha = hb;

スライスはしません。代わりに、コンパイラは単にエラーを出し、関連する型ではないことを通知するholder<A>ためholder<B>、割り当てを行うことはできません。明示的なキャストを追加しないと、コンパイルされません。

于 2009-10-08T23:21:23.993 に答える
2

あなたは正しいですが、それらは同じではありません: を評価することはできませんa->stuff

于 2009-10-08T23:19:44.183 に答える