スマートポインターでスライスすることは可能ですか?
-
20-09-2019 - |
質問
スライスを正しく理解していれば、これがポインターやスマートポインターで起こるとは思わない。たとえば、あなたが持っていた場合:
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」に割り当てられたときに変更されないということです。
私の理解を確認または拒否するか、これに関連する落とし穴を教えてください。
解決
スマートポインターは依然としてポインターであるため、そのような割り当てはスライスしません。スライスは、ポインターではなく値を扱うときにのみ発生します。ただし、テンプレートは、ポイントのアイテム間の関係について知らないため、BはAから派生していても、 shared_pointer<B>
派生していません shared_pointer<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; }
};
さて、1つの値を別の値に割り当てようとすると、スライスを引き起こすように:
holder<A> ha;
holder<B> hb;
A a;
B b;
ha = a;
hb = b;
ha = hb;
スライスはありません。代わりに、コンパイラは単にエラーを与えてくれます。 holder<A>
と holder<B>
関連するタイプではないため、割り当ては発生しません - 明示的なキャストを追加しないと、単にコンパイルされません。
他のヒント
あなたは正しいですが、彼らは同じではありません:あなたは評価することはできません a->stuff
.