4

さて、誰もがペストのように生のポインターを避け、スマートポインターを好むべきであることを知っていますが、このアドバイスはコンテナーを実装するときに適用されますか?これは私が達成しようとしていることです:

template<typename T> class AVLTreeNode {
public:
    T data;
    unique_ptr<AVLTreeNode<T>> left, right;
    int height;
}

Unique_ptrは、エレガントな方法で同じオブジェクトを一時的に指す複数のrawポインターを持つことができないため、コンテナー関数の記述をより面倒にする可能性があります。例えば:

unique_ptr<AVLTreeNode<T>> rotate_right(unique_ptr<AVLTreeNode<T>> n1)
{
    unique_ptr<AVLTreeNode<T>> n2 = n1->left;

    n1->left = n2->right;
    n2->right = n1;
    // n1 must now be referenced through the longer name n2->right from now on
    n2->right->recalculate_height();
    n2->recalculate_height();

    return n2;
}

(この例では大したことではありませんが、どのように問題になるか想像できます)。このような問題を、古き良き、、、およびrawポインターを使用してコンテナーを実装する必要があるという強力なヒントとしてとらえる必要がありnewますdeleteか?デストラクタを作成しないようにするだけでも、非常に多くの問題が発生するようです。

4

5 に答える 5

7

あなたが示すように、コンテナを実装するとき、私は通常スマートポインタを使用しません。生のポインター (imho) は疫病のように避けるべきではありません。メモリの所有権を強制する場合は、スマート ポインターを使用します。しかし通常、コンテナーでは、データ構造を構成するポインターが指すメモリーをコンテナーが所有します。

あなたのデザインで、 がAVLTreeNode左右の子を一意に所有し、それを で表現したい場合、それでunique_ptr問題ありません。AVLTreeしかし、それがすべての s を所有しAVLTreeNode、生のポインターでそれを行うことを希望する場合、それは同じように有効です (そして、私が通常それをコーディングする方法です)。

私を信じてください、私はアンチ スマート ポインターではありません。を発明したのは私ですunique_ptr。しかしunique_ptr、ツールボックスの単なる別のツールです。ツール ボックスに優れたスマート ポインターを用意しても万能ではありません。それらを盲目的にすべてに使用することは、慎重な設計に代わるものではありません。

コメントに応答するための更新(コメント ボックスが小さすぎた):

私は生のポインターをよく使用します (所有することはめったにありません)。私のコーディング スタイルの良いサンプルが、オープン ソース プロジェクトlibc++にあります。「SVN を参照」リンクの下でソースを参照できます。

通常の割り当て解除がデストラクタの外部で発生した場合でも、例外の安全性に関する懸念から、リソースのすべての割り当てをどこかのデストラクタで割り当て解除できるようにすることを好みます。割り当てが単一のポインターによって所有されている場合、通常、スマート ポインターはツール ボックスの中で最も便利なツールです。割り当てがポインターよりも大きなもの (コンテナーやクラスなど) によって所有されているEmployee場合、生のポインターは、より大きなオブジェクトを構成するデータ構造の便利な部分であることがよくあります。

最も重要なことは、スマート ポインター、コンテナーなど、どのオブジェクトがそのリソースを所有しているかを知らずにリソースを割り当てないことです。

于 2011-03-29T14:03:54.130 に答える
3

あなたが提示したコードは問題なくコンパイルされます

#include <memory>
template<typename T> class AVLTreeNode {
public:
    T data;
    std::unique_ptr<AVLTreeNode<T>> left, right;
    int height;
};
int main()
{
    AVLTreeNode<int> node;
}

テストのコンパイル: https://ideone.com/aUAHs

個人的には、ツリーにスマート ポインターを使用していました。std::auto_ptr

rotate_right に関しては、いくつかの呼び出しで実装できます。unique_ptr::swap

于 2011-03-29T10:40:01.387 に答える
0

std::shared_ptrこれらの制限はありません。特に、複数shared_ptrのインスタンスが同じオブジェクトを参照できます。

于 2011-03-29T11:06:29.573 に答える
0

Herb Shutter は、彼の GoTW シリーズで shared_ptr をパラメーターとして使用しないことについて、非常に明確なガイドラインを持っています。

ガイドライン: 所有権の共有や譲渡など、スマート ポインター自体を使用または操作する場合を除き、スマート ポインターを関数パラメーターとして渡さないでください。

この...

ガイドライン: スマート ポインターではなく、値、*、または & でオブジェクトを渡すことをお勧めします。

于 2016-12-20T08:10:38.757 に答える
0

小さな修正: 生のポインターは疫病のように避けるべきではありません (おっと、誰もが事実を知っているわけではありません) が、可能な場合は手動のメモリ管理を避ける必要があります (動的配列またはスマートポインターの代わりにコンテナーを使用することにより)。一時ストレージ用の unique_ptr の get()。

于 2011-03-29T10:54:18.687 に答える