私はまだCスタイルのものがたくさんあることがわかりました。私は今、生のポインタの使用量を減らして新しい千年紀を受け入れるよう努めています。私はunique_ptr<BaseClass>
というベクトルを持っていて、それぞれが派生クラスのオブジェクトを指しています。私は派生クラスのオブジェクトの1つを参照する良い方法を取得しようとしています。現時点では、.get()
関数を使用してこれを派生クラスにキャストします。型キャストでunique_ptrのオブジェクトへの参照を作成する
しかし、私が理解しているように、.get()
は、ほとんどが生のポインタを主張するレガシーコードとのインタフェースにあり、その使用は避けるべきです。 unique_ptr
内のオブジェクトへの別のポインタを持つことは、避けることができれば素晴らしいスタイルのようには見えません。取得を使用せずに、派生クラスオブジェクトへの参照を取得する方法はありますか?またはオブジェクトを処理する他の便利な方法?
#include <iostream>
#include <vector>
class Fruit {
public:
double size = 0;
virtual ~Fruit() = default;
};
class Apple : public Fruit {
public:
bool hasLeaf = false;
};
void doAppleStuff(std::vector<std::unique_ptr<Fruit> > &apples) {
// assume we know that element [0] exists and it is definitely of type Apple
auto apple = static_cast<Apple *> (apples[0].get()); // is there a better option?
if (apple->hasLeaf) {
std::cout << "We can leaf now" << std::endl;
} else {
std::cout << "We are pitiably leafless" << std::endl;
}
}
int main() {
std::vector<std::unique_ptr<Fruit> > fruitVec;
auto apple = new Apple;
apple->hasLeaf = true;
std::unique_ptr<Fruit> applePt(apple);
fruitVec.push_back(std::move(applePt));
doAppleStuff(fruitVec);
return 0;
}
(私はそれがC++ 14からmake_unique
と主な機能を短縮するために、おそらく可能だと思う):
はここで単純化されたコード例です。
このようなことをするのは良いコーディングスタイルですか?
auto &apple = *static_cast<Apple *> (apples[0].get());
"Downcasting" unique_ptr<Base> to unique_ptr<Derived>の答えがそれを解放し、派生クラスに新しいunique_ptr
を再作成することによってunique_ptr
を「キャスト」する方法を概説し、私は本当にしたくないとしてそれは、ここでは該当いないようですユニークなポインタのベクトルを混乱させる(私が何かを見逃していない限り)。あなたは、ポインタが非nullptr
であることがわかっている場合は
と呼ば
に
doAppleStuff
を変更、あなたのことですコードは現在UBです。 – Jarod42基本クラスへのポインタを使用してクラスを格納することを主張する場合、いくつかの仮想メソッド(特にデストラクタ)を宣言し、アップキャストの代わりに呼び出す必要があります。 – VTT
@ Jarod42優れた点...私はバーチャルデストラクタを追加するコードを編集します –