[解決済み] shared_ptr<Derived>をshared_ptr<Base>として渡す。
質問
を渡すのに最適な方法は何ですか?
shared_ptr
を受け取る関数に、派生型の
shared_ptr
を取る関数に変更できますか?
私は一般的に
shared_ptr
を参照で渡し、無駄なコピーを避けるようにしています。
int foo(const shared_ptr<bar>& ptr);
のようにしてもうまくいきません。
int foo(const shared_ptr<Base>& ptr);
...
shared_ptr<Derived> bar = make_shared<Derived>();
foo(bar);
を使うことができた。
foo(dynamic_pointer_cast<Base, Derived>(bar));
が、これは2つの理由から最適ではないようです。
-
A
dynamic_cast
は単純な派生からベースへのキャストには少し過剰なようです。 -
私が理解しているように
dynamic_pointer_cast
は関数に渡すポインタのコピーを (一時的なものではありますが) 作成します。
もっと良い解決策はないのでしょうか?
後世のために更新します。
ヘッダーファイルの欠落の問題であることが判明しました。また、私がここで行おうとしていたことは、アンチパターンと考えられています。一般的に
-
オブジェクトのライフタイムに影響を与えない (すなわち、オブジェクトはその関数の間、有効であり続ける) 関数は、例えば
int foo(bar& b)
. -
以下のような機能 消費する オブジェクトを消費する (すなわち、与えられたオブジェクトの最終的な利用者である) 関数は、そのオブジェクトのために
unique_ptr
を値として取ります。int foo(unique_ptr<bar> b)
. 呼び出し側はstd::move
を関数に渡す必要があります。 -
オブジェクトのライフタイムを延長する関数は
shared_ptr
を値として取るべきです。int foo(shared_ptr<bar> b)
. を避けるようにという通常のアドバイス 循環参照 が適用されます。
ハーブ・サッターの バック・トゥ・ベーシックス をご覧ください。
どのように解決するのですか?
しかし
Base
と
Derived
は共変量で、それらへの生のポインタはそれに応じて動作します。
shared_ptr<Base>
と
shared_ptr<Derived>
は
ではない
共変である。そのため
dynamic_pointer_cast
はこの問題を処理するための正しくて最も簡単な方法です。
(
編集してください。
static_pointer_cast
の方が適切でしょう。なぜなら、 derived から base にキャストしているので、安全であり、実行時のチェックも必要ないからです。以下のコメントを参照してください)。
しかし、もしあなたの
foo()
関数が寿命の延長に参加したくない (むしろオブジェクトの共有所有権に参加したくない) 場合は
const Base&
を受け入れ
shared_ptr
に渡すときは
foo()
.
void foo(const Base& base);
[...]
shared_ptr<Derived> spDerived = getDerived();
foo(*spDerived);
余談ですが
shared_ptr
の型は共変できないので、共変の戻り値の型をまたぐ暗黙の変換のルールは
shared_ptr<T>
.
関連
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み】std::cin.getline( ) vs. std::cin
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。
-
[解決済み] const std::string & をパラメータとして渡す時代は終わったのでしょうか?
-
[解決済み] C++のmake_sharedと通常のshared_ptrの違いについて
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み】C++の余分な資格エラー
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み】Enterキーを押して続行する
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された