スマートポインターとは何ですか?いつ使用すべきですか?


1820

スマートポインターとは何ですか?いつ使用すべきですか?



2
Visual Studio 2005でのstd :: auto_ptrの実装がひどく壊れていることに注意してください。<BR> http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98871 <BR> http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101842使用します代わりにブーストします。
Richard

25
このテーマに関する2つの優れた記事:- スマートポインター-何、なぜ、どれ?- 今週の第一人者#25
Lazer

1
ここでは異なる味のスマートポインタ作成の核心にアレキの(無料)の章です:informit.com/articles/article.aspx?p=31529を 彼の実装では、彼は彼が(望んでいる属性を指定し、「政策」としてのテンプレート引数を使用していますたとえば、参照カウント)、標準ライブラリは個別のクラスを使用します。std :: unique_ptrのようなものを可能にするために右辺値参照が利用可能になる前に彼も書いていることに注意してください。
金属

上記の質問にもう1つポイントを追加したいと思います。スマートポインターstd :: shared_ptrには添え字演算子がなく、ポンター演算をサポートしていません。get()を使用して組み込みポインターを取得できます。
シュレッシュm 2018

回答:


1884

更新

この答えはかなり古く、そのため、当時「良かった」ものを説明しています。これは、Boostライブラリによって提供されたスマートポインターでした。C ++ 11ので、標準ライブラリには、十分なスマートポインタの種類を提供している、とあなたはの使用を支持すべきであるstd::unique_ptrstd::shared_ptrstd::weak_ptr

もありましたstd::auto_ptr。これはスコープ付きポインタに非常に似ていましたが、コピーされる「特別な」危険な機能も持っていました。
C ++ 11で非推奨になり、C ++ 17削除されたため、使用しないでください。

std::auto_ptr<MyObject> p1 (new MyObject());
std::auto_ptr<MyObject> p2 = p1; // Copy and transfer ownership. 
                                 // p1 gets set to empty!
p2->DoSomething(); // Works.
p1->DoSomething(); // Oh oh. Hopefully raises some NULL pointer exception.

古い答え

スマートポインターは、「生」(または「ベア」)C ++ポインターをラップするクラスであり、ポイントされているオブジェクトの有効期間を管理します。単一のスマートポインター型はありませんが、それらすべてが実用的な方法で生のポインターを抽象化しようとします。

生のポインターよりもスマートポインターを優先する必要があります。ポインターを使用する必要があると思われる場合(実際に使用するかどうかを最初に検討してください)、通常はスマートポインターを使用することをお勧めします。これにより、生のポインターに関する多くの問題が軽減されます。

生のポインタを使用すると、プログラマはオブジェクトが不要になったときに明示的に破棄する必要があります。

// Need to create the object to achieve some goal
MyObject* ptr = new MyObject(); 
ptr->DoSomething(); // Use the object in some way
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception...?

比較によるスマートポインターは、オブジェクトが破棄されるタイミングに関するポリシーを定義します。それでもオブジェクトを作成する必要がありますが、オブジェクトを破棄することを心配する必要はありません。

SomeSmartPtr<MyObject> ptr(new MyObject());
ptr->DoSomething(); // Use the object in some way.

// Destruction of the object happens, depending 
// on the policy the smart pointer class uses.

// Destruction would happen even if DoSomething() 
// raises an exception

使用中の最も単純なポリシーには、boost::scoped_ptrまたはによって実装されるような、スマートポインターラッパーオブジェクトのスコープが含まれますstd::unique_ptr

void f()
{
    {
       std::unique_ptr<MyObject> ptr(new MyObject());
       ptr->DoSomethingUseful();
    } // ptr goes out of scope -- 
      // the MyObject is automatically destroyed.

    // ptr->Oops(); // Compile error: "ptr" not defined
                    // since it is no longer in scope.
}

std::unique_ptrインスタンスはコピーできないことに注意してください。これにより、ポインターが複数回(誤って)削除されるのを防ぎます。ただし、それへの参照を、呼び出す他の関数に渡すことはできます。

std::unique_ptrsは、オブジェクトの存続期間を特定のコードブロックに関連付けたい場合や、別のオブジェクト内のメンバーデータとして埋め込んだ場合は、その他のオブジェクトの存続期間に役立ちます。オブジェクトは、コードの包含ブロックが終了するまで、または包含オブジェクト自体が破棄されるまで存在します。

より複雑なスマートポインターポリシーには、ポインターの参照カウントが含まれます。これにより、ポインタをコピーできます。オブジェクトへの最後の「参照」が破棄されると、オブジェクトは削除されます。このポリシーはboost::shared_ptrおよびによって実装されていstd::shared_ptrます。

void f()
{
    typedef std::shared_ptr<MyObject> MyObjectPtr; // nice short alias
    MyObjectPtr p1; // Empty

    {
        MyObjectPtr p2(new MyObject());
        // There is now one "reference" to the created object
        p1 = p2; // Copy the pointer.
        // There are now two references to the object.
    } // p2 is destroyed, leaving one reference to the object.
} // p1 is destroyed, leaving a reference count of zero. 
  // The object is deleted.

参照カウントポインターは、オブジェクトの存続期間がはるかに複雑で、コードの特定のセクションや別のオブジェクトに直接関連付けられていない場合に非常に役立ちます。

カウントされたポインタを参照することには1つの欠点があります—ぶら下がっている参照が作成される可能性があります。

// Create the smart pointer on the heap
MyObjectPtr* pp = new MyObjectPtr(new MyObject())
// Hmm, we forgot to destroy the smart pointer,
// because of that, the object is never destroyed!

別の可能性は循環参照を作成することです:

struct Owner {
   std::shared_ptr<Owner> other;
};

std::shared_ptr<Owner> p1 (new Owner());
std::shared_ptr<Owner> p2 (new Owner());
p1->other = p2; // p1 references p2
p2->other = p1; // p2 references p1

// Oops, the reference count of of p1 and p2 never goes to zero!
// The objects are never destroyed!

この問題を回避するために、BoostとC ++ 11の両方でを定義して、weak_ptrへの弱い(カウントされていない)参照を定義していますshared_ptr


7
あなたは意味するかstd::auto_ptr<MyObject> p1 (new MyObject());の代わりにstd::auto_ptr<MyObject> p1 (new Owner());
Mateen Ulhaq、2011

35
素晴らしい答え。それがc ++ 11用に更新されているといいですね。新しい11標準に関する情報を探すためにこの回答を見つけました。将来の訪問者が更新された情報を見つけることができればすばらしいと思います。auto_ptrが廃止されたことを知っています。説明されているとおり、shated_ptrとweak_ptrが存在すると私は考えています。また、scoped_ptrは、標準ではunique_ptrになっていると思います。これに該当する場合、この回答を更新していただけますか?
SaulBack 2012

16
ぶら下がっている参照を作成する可能性は、参照カウントされたポインターを参照することの欠点であると言うことは全く正気ではありません。ぶら下がっている可能性のある参照は、C ++ポインターの欠点です。実際、スマートポインタが緩和することを意図しいるのはまさにその欠点です。
マイケルドースト2014

16
(例で行ったように)スマートポインターへのポインターを宣言すると、スマートポインターのすべての利点が故意に放棄されます。これは欠点や設計上の欠陥ではなく、想像できる最もばかげた使用法です。
マイケルドースト2014

3
const std::auto_ptrC ++ 03に悩まされている場合は、A を使用しても安全です。C ++ 11にアクセスできるようになるまで、pimplパターンにかなり使用しました。
Toby Speight

303

最近のC ++(C ++ 11以降)の最近の簡単な答えは次のとおりです。

  • スマートポインターとは何ですか?
    これは、ポインタのように値を使用できるタイプですが、自動メモリ管理の追加機能を提供します。スマートポインタが使用されなくなると、それが指すメモリが割り当て解除されます(Wikipediaの詳細な定義も参照)。
  • いつ使用すべきですか?
    メモリの所有権の追跡、割り当てまたは割り当て解除を含むコード。多くの場合、スマートポインターを使用すると、これらのことを明示的に行う必要がなくなります。
  • しかし、どの場合にどのスマートポインターを使用すればよいですか?
    • std::unique_ptr同じオブジェクトへの複数の参照を保持するつもりがない場合に使用します。たとえば、あるスコープに入るときに割り当てられ、スコープから出るときに割り当て解除されるメモリへのポインタにそれを使用します。
    • std::shared_ptr複数の場所からオブジェクトを参照したい場合、およびこれらの参照がすべてなくなるまでオブジェクトの割り当てを解除したくない場合に使用します。
    • std::weak_ptr複数の場所からオブジェクトを参照したい場合に使用します-無視して割り当てを解除してもよい参照の場合(つまり、逆参照しようとするとオブジェクトがなくなっていることに注意してください)。
    • boost::スマートポインターを使用したり、std::auto_ptr必要に応じて読み上げたりできる特別な場合を除いて、使用しないでください。
  • ねえ、私はどちらを使うべきか尋ねませんでした!
    ああ、でも本当にやりたかったのですが、認めます。
  • では、いつ通常のポインタを使用すればよいですか?
    ほとんどの場合、メモリの所有権に気付かないコードです。これは通常、他の場所からポインターを取得し、割り当ても割り当て解除もせず、実行が長持ちするポインターのコピーを格納しない関数にあります。

5
スマート(所有)ポインターは適切なメモリ管理に役立ちますが、生(非所有)ポインターはデータ構造の他の組織的な目的にも役立ちます。Herb Sutterは、CppCon 2016でこの問題について素晴らしいプレゼンテーションを行いました。これは、YouTubeで確認できます:C ++におけるリークの自由...デフォルトでは。
wiktor.wandachowicz 2016年

1
@ wiktor.wandachowiczはT*にあるstd::unique_ptr<T>std::weak_ptr<T>にあるstd::shared_ptr<T>
Caleth

@Caleth:いいえ、そうは思いません。
einpoklum

1
@TonyTannous:敬意を表して-これは大きな編集でした。抽象的である私の答えにはそれが必要だとは思いません。コメントにリンクして、例を別の回答にすることをお勧めします。
アインポクルム

112

スマートポインターは、自動メモリ割り当て解除、参照カウントなどのいくつかの追加機能を備えたポインターのようなタイプです。

小さなイントロページで提供されていますスマートポインタ-何を、なぜ、どのましたか?

単純なスマートポインター型の1つはstd::auto_ptr(C ++標準のチャプター20.4.5)です。これにより、スコープ外のときにメモリを自動的に割り当て解除でき、例外がスローされたときの単純なポインターの使用よりも堅牢ですが、柔軟性は低くなります。

別の便利なタイプはboost::shared_ptr、参照カウントを実装し、オブジェクトへの参照が残っていないときに自動的にメモリの割り当てを解除するタイプです。これは、メモリリークの回避に役立ち、RAIIの実装に簡単に使用できます。

サブジェクトは、David Vandevoorde、Nicolai M. Josuttis著の「C ++ Templates:The Complete Guide」の章の第20章「スマートポインターで詳しく説明されています。カバーするいくつかのトピック:

  • 例外からの保護
  • ホルダー(注意:std :: auto_ptrは、そのようなタイプのスマートポインターの実装です)
  • リソース取得は初期化です(これは、C ++での例外安全なリソース管理によく使用されます)
  • ホルダーの制限
  • 参照カウント
  • 同時カウンターアクセス
  • 破壊と解放

2
警告std::auto_ptrは非推奨であり、誤って所有権を譲渡する可能性があるため、お勧めしません。- C ++ 11はブースト、使用の必要性を削除します std::unique_ptrstd::shared_ptrそしてstd::weak_ptr
ninMonkey

42

Chris、Sergdev、およびLlyodによって提供された定義は正しいです。ただし、私の人生を単純にするために、より単純な定義を好みます。スマートポインターは、単純に-> and *演算子をオーバーロードするクラスです。あなたのオブジェクトは、意味的にポインタのように見えますが、あなたはそれが参照カウント、自動破壊等を含む方法クーラーの事を、間に合わせることができ、どの手段 shared_ptrauto_ptr、ほとんどの場合で十分ですが、小さな特異性の独自のセットと一緒に来ます。


30

スマートポインターは、「char *」のような通常の(型付き)ポインターに似ていますが、ポインター自体がスコープ外に出た場合、ポインターが指しているものも削除されます。"->"を使用することで、通常のポインタと同じように使用できますが、データへの実際のポインタが必要な場合は使用できません。そのためには、「&* ptr」を使用できます。

次の場合に便利です。

  • newで割り当てる必要があるが、そのスタック上の何かと同じ存続期間を持たせたいオブジェクト。オブジェクトがスマートポインターに割り当てられている場合、プログラムがその関数/ブロックを終了すると、オブジェクトは削除されます。

  • クラスのデータメンバー。オブジェクトが削除されると、デストラクタに特別なコードがなくても、所有されているすべてのデータも削除されます(デストラクタが仮想であることを確認する必要があります。これは、ほとんどの場合、適切です)。 。

次のような場合、スマートポインタを使用したくない場合があります。

  • ...ポインタは実際にデータを所有するべきではありません...つまり、データを使用しているだけで、それを参照している関数を存続させたい場合。
  • ...スマートポインタ自体は、ある時点で破棄されることはありません。決して破壊されないメモリ内に置かないでください(動的に割り当てられているが明示的に削除されないオブジェクト内など)。
  • ... 2つのスマートポインタが同じデータを指す場合があります。(ただし、それを処理するよりスマートなポインターがあります...これは参照カウントと呼ばれます。)

以下も参照してください。


18

ほとんどの種類のスマートポインターは、ポインターへのオブジェクトの破棄を処理します。オブジェクトを手動で破棄する必要がなくなったため、非常に便利です。

最も一般的に使用されるスマートポインターはstd::tr1::shared_ptr(またはboost::shared_ptr)であり、あまり一般的ではありませんが、std::auto_ptrです。の常用をお勧めしますshared_ptr

shared_ptrは非常に用途が広く、オブジェクトを「DLLの境界を越えて渡す」必要がある場合(libcコードとDLLの間で異なるが使用される場合の一般的な悪夢のようなケース)を含む、さまざまな廃棄シナリオを扱います。


18

スマートポインターは、ポインターのように機能するオブジェクトですが、さらに、構築、破棄、コピー、移動、逆参照の制御を提供します。

独自のスマートポインターを実装することもできますが、多くのライブラリは、それぞれに異なる長所と短所を持つスマートポインターの実装も提供しています。

たとえば、Boostは次のスマートポインター実装を提供します。

  • shared_ptr<T>T参照カウントを使用してオブジェクトが不要になった時期を判断するためのポインタです。
  • scoped_ptr<T>範囲外になると自動的に削除されるポインタです。割り当てはできません。
  • intrusive_ptr<T>別の参照カウントポインタです。これは、よりも優れたパフォーマンスを提供しますが、独自の参照カウントメカニズムを提供するshared_ptrタイプが必要Tです。
  • weak_ptr<T>は弱いポインタであり、shared_ptr循環参照を回避するためにと連携して機能します。
  • shared_array<T>はに似てshared_ptrいますが、の配列用ですT
  • scoped_array<T>はに似てscoped_ptrいますが、の配列用ですT

これらはそれぞれの1つの線形説明であり、必要に応じて使用できます。詳細と例については、Boostのドキュメントを参照してください。

さらに、C ++標準ライブラリは3つのスマートポインタを提供します。std::unique_ptrユニークな所有権のために、std::shared_ptr所有権を共有してためstd::weak_ptrstd::auto_ptrC ++ 03に存在していましたが、現在は非推奨です。


scoped_ptrローカルで宣言const unique_ptrされていない理由を説明してください-スコープを終了すると削除されます。
einpoklum 2015

11

同様の回答のリンクは次のとおりです。http//sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

スマートポインターは、通常のポインターのように動作、外観、および操作するオブジェクトですが、より多くの機能を提供します。C ++では、スマートポインターは、ポインターをカプセル化し、標準のポインター演算子をオーバーライドするテンプレートクラスとして実装されます。通常のポインターよりも多くの利点があります。これらは、nullポインターまたはヒープオブジェクトへのポインターとして初期化されることが保証されています。nullポインターによる間接参照がチェックされます。削除する必要はありません。オブジェクトへの最後のポインタがなくなると、オブジェクトは自動的に解放されます。これらのスマートポインターの1つの重要な問題は、通常のポインターとは異なり、継承を尊重しないことです。スマートポインタは、ポリモーフィックコードでは魅力的ではありません。以下は、スマートポインターの実装例です。

例:

template <class X>
class smart_pointer
{
          public:
               smart_pointer();                          // makes a null pointer
               smart_pointer(const X& x)            // makes pointer to copy of x

               X& operator *( );
               const X& operator*( ) const;
               X* operator->() const;

               smart_pointer(const smart_pointer <X> &);
               const smart_pointer <X> & operator =(const smart_pointer<X>&);
               ~smart_pointer();
          private:
               //...
};

このクラスは、タイプXのオブジェクトへのスマートポインターを実装します。オブジェクト自体はヒープに配置されます。使用方法は次のとおりです。

smart_pointer <employee> p= employee("Harris",1333);

他のオーバーロードされた演算子と同様に、pは通常のポインターのように動作します。

cout<<*p;
p->raise_salary(0.5);

9

http://en.wikipedia.org/wiki/Smart_pointer

コンピュータサイエンスでは、スマートポインタは、自動ガベージコレクションや境界チェックなどの追加機能を提供しながら、ポインタをシミュレートする抽象的なデータ型です。これらの追加機能は、効率を維持しながら、ポインターの誤用によって引き起こされるバグを減らすことを目的としています。スマートポインタは通常、メモリ管理の目的で、それらを指すオブジェクトを追跡します。ポインタの誤用はバグの主な原因です。ポインタを使用して作成されたプログラムで実行する必要がある定数の割り当て、割り当て解除、参照は、メモリリークが発生する可能性が非常に高くなります。スマートポインターは、リソースの割り当てを自動的に解除してメモリリークを防止しようとします。オブジェクトへのポインター(または一連のポインターの最後)が破棄されると、


6

TをこのチュートリアルのクラスとするC ++のポインターは、3つのタイプに分けることができます。

1)生のポインタ

T a;  
T * _ptr = &a; 

それらは、メモリ内の場所へのメモリアドレスを保持します。プログラムを追跡するのが難しくなるので、注意して使用してください。

constデータまたはアドレスを持つポインター{逆方向読み取り}

T a ; 
const T * ptr1 = &a ; 
T const * ptr1 = &a ;

constであるデータ型Tへのポインター。つまり、ポインタを使用してデータ型を変更することはできません。すなわち*ptr1 = 19; 動作しないでしょう。ただし、ポインタを移動することはできます。すなわちptr1++ , ptr1--; などは動作します。逆方向に読む:constであるT型へのポインタ

  T * const ptr2 ;

データ型Tへのconstポインター。つまり、ポインターを移動することはできませんが、ポインターが指す値を変更することはできます。つまり、機能し*ptr2 = 19ますが、機能しptr2++ ; ptr2--ません。逆方向に読む:型Tへのconstポインター

const T * const ptr3 ; 

constデータ型Tへのconstポインター。つまり、ポインターを移動することも、データ型ポインターをポインターに変更することもできません。すなわち。ptr3-- ; ptr3++ ; *ptr3 = 19;動作しないでしょう

3)スマートポインター:{ #include <memory>}

共有ポインター

  T a ; 
     //shared_ptr<T> shptr(new T) ; not recommended but works 
     shared_ptr<T> shptr = make_shared<T>(); // faster + exception safe

     std::cout << shptr.use_count() ; // 1 //  gives the number of " 
things " pointing to it. 
     T * temp = shptr.get(); // gives a pointer to object

     // shared_pointer used like a regular pointer to call member functions
      shptr->memFn();
     (*shptr).memFn(); 

    //
     shptr.reset() ; // frees the object pointed to be the ptr 
     shptr = nullptr ; // frees the object 
     shptr = make_shared<T>() ; // frees the original object and points to new object

参照カウントを使用して実装され、ポインターが指すオブジェクトを指す「もの」の数を追跡します。このカウントが0になると、オブジェクトは自動的に削除されます。つまり、オブジェクトを指すすべてのshare_ptrがスコープから外れると、オブジェクトが削除されます。これにより、newを使用して割り当てたオブジェクトを削除しなければならないという頭痛がなくなります。

弱いポインタ: 共有ポインタを使用するときに発生する循環参照の処理に役立ちます。2つの共有ポインタが指す2つのオブジェクトがあり、相互に共有ポインタを指す内部共有ポインタがある場合、循環参照があり、オブジェクトはありません。共有ポインタが範囲外になったときに削除されます。これを解決するには、内部メンバーをshared_ptrからweak_ptrに変更します。注:弱いポインターが指す要素にアクセスするには、lock()を使用して、weak_ptrを返します。

T a ; 
shared_ptr<T> shr = make_shared<T>() ; 
weak_ptr<T> wk = shr ; // initialize a weak_ptr from a shared_ptr 
wk.lock()->memFn() ; // use lock to get a shared_ptr 
//   ^^^ Can lead to exception if the shared ptr has gone out of scope
if(!wk.expired()) wk.lock()->memFn() ;
// Check if shared ptr has gone out of scope before access

参照:std :: weak_ptrが役立つのはいつですか?

ユニークなポインター: 独占的な所有権を持つ軽量のスマートポインター。ポインター間でオブジェクトを共有せずに、ポインターが一意のオブジェクトを指す場合に使用します。

unique_ptr<T> uptr(new T);
uptr->memFn(); 

//T * ptr = uptr.release(); // uptr becomes null and object is pointed to by ptr
uptr.reset() ; // deletes the object pointed to by uptr 

一意のptrが指すオブジェクトを変更するには、移動セマンティクスを使用します

unique_ptr<T> uptr1(new T);
unique_ptr<T> uptr2(new T);
uptr2 = std::move(uptr1); 
// object pointed by uptr2 is deleted and 
// object pointed by uptr1 is pointed to by uptr2
// uptr1 becomes null 

参照:それらは本質的にconstポインターとして考えることができます。つまり、constであり、より良い構文では移動できないポインターです。

参照:C ++のポインター変数と参照変数の違いは何ですか?

r-value reference : reference to a temporary object   
l-value reference : reference to an object whose address can be obtained
const reference : reference to a data type which is const and cannot be modified 

参照:https : //www.youtube.com/channel/UCEOGtxYTB6vo6MQ-WQ9W_nQ この質問を指摘してくれたAndreに感謝します


3

スマートポインターはクラスであり、通常のポインターのラッパーです。通常のポインターとは異なり、スマートポイントのライフサークルは参照カウント(スマートポインターオブジェクトが割り当てられた回数)に基づいています。したがって、スマートポインタが別のスマートポインタに割り当てられると、内部参照カウントにプラスが加算されます。また、オブジェクトがスコープから外れると、参照カウントからマイナスが引かれます。

自動ポインタは似ていますが、スマートポインタとはまったく異なります。これは、自動ポインターオブジェクトが変数のスコープから外れるたびにリソースの割り当てを解除する便利なクラスです。ある程度、(動的に割り当てられたメモリへの)ポインタが(コンパイル時に静的に割り当てられた)スタック変数と同様に機能するようにします。


2

スマートポインターは、メモリの割り当て解除、リソースの共有、転送について心配する必要がないものです。

Javaで割り当てが機能するのと同じように、これらのポインターを非常にうまく使用できます。java Garbage Collectorではトリックを実行しますが、Smart Pointersでは、トリックはデストラクタによって実行されます。


1

既存の回答は適切ですが、スマートポインターが解決しようとしている問題に対する(完全な)回答ではない場合の対処方法については説明しません。

とりわけ、(他の回答でよく説明されている)スマートポインターの使用は、抽象クラスを関数の戻り値の型としてどのように使用するかに対する可能な解決策です。これはこの質問の複製としてマークされています。ただし、C ++で戻り値の型として抽象(または実際には任意の)基本クラスを指定したいかどうかを尋ねる最初の質問は、「本当にどういう意味ですか?」です。ブーストポインターコンテナーライブラリのドキュメントに、C ++での慣用的なオブジェクト指向プログラミング(および他の言語との違い)に関するよい議論があります。要約すると、C ++では所有権について考える必要があります。どのスマートポインターが役立ちますが、唯一の解決策ではないか、または常に完全な解決策(ポリモーフィックコピーを提供しない)であり、常にインターフェイスで公開する必要がある解決策ではありません(そして関数の戻りがひどいように聞こえます)インターフェースによく似ています)。たとえば、参照を返すだけで十分な場合があります。しかし、これらすべてのケース(スマートポインター、ポインターコンテナー、または単に参照を返す)では、戻りから何らかの参照形式に変更しました。本当にコピーが必要な場合は、C ++のボイラープレート「イディオム」を追加するか、C ++の慣用的な(またはその他の)OOPを超えて、Adobe PolyBoost.TypeErasureなどのライブラリを使用したより一般的なポリモーフィズムに移動する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.