1

使用するプログラマーboost::shared_ptrは、リソース リークが発生しないようにサイクルを回避する必要があります。一般的なアドバイスはboost::weak_ptr、そのようなサイクルが作成される可能性がある場合に a を使用することです。ただし、そうすることで、 を使用することを好むかもしれないがshared_ptr、サイクルの問題のためだけに使用しなかったという意図のギャップが生じます。

ただし、サイクル内のすべてのポインターの参照カウントをリンクすることにより、サイクルの問題を回避する特別な種類の shared_ptr を作成できるはずだと私には思えます。で、やり方は思いつくので、そんなものはあるのだろうか。

私が頭がおかしいわけではないことを証明するために、またはおそらく私が頭がおかしいことを証明するために、次のよく考えられていない醜い概念の証明を提供します。

#define BOOST_NO_MEMBER_TEMPLATE_FRIENDS

#include <boost/shared_ptr.hpp>
#include <iostream>

template <typename T>
struct shared_count_ptr
{
    boost::shared_ptr<T> innerPtr;
    template <typename TT>
    void link( boost::shared_ptr<T> & sharedPtr, boost::shared_ptr<TT> & linked )
    {
        innerPtr    = sharedPtr;
        innerPtr.pn = linked.pn;
    }
};

struct Hand;
struct Arm
{
    Arm()  { std::cout << "Creating Arm\n";   }
    ~Arm() { std::cout << "Destroying Arm\n"; }

    shared_count_ptr<Hand> hand;
};

struct Hand
{
    Hand()  { std::cout << "Creating Hand\n";   }
    ~Hand() { std::cout << "Destroying Hand\n"; }

    shared_count_ptr<Arm> arm;
};

int main()
{
    boost::shared_ptr<Arm> savedArm;

    std::cout << "Scope 0 entered\n";
    {
        std::cout << "\tScope 1 entered\n" ;

        boost::shared_ptr<Arm> arm( new Arm );
        {
            std::cout << "\t\tScope 2 entered\n";
            boost::shared_ptr<Hand>  hand( new Hand );

            hand->arm.link( arm, arm->hand );
            arm->hand.innerPtr = hand;

            savedArm = arm;
        }
        std::cout << "\t\tScope 2 exited\n";
    }
    std::cout << "\tScope 1 exited\n";
    std::cout << "\tScope 0 about to exit\n";

    return 0;
}

一般的な概念は、想像上の人の目にはshared_count_ptr、腕と手は事実上同じオブジェクトであるということです。

そう:

  • そのような考えはすでに存在していboostますか?
  • そうでない場合、それはひどい考えだからですか?(それとも、何か賢いことを思いついたのですか?)
4

2 に答える 2

2

ここに簡単なテストがあります。プログラムが頂点 0 のみを指すように、17 個の頂点で完全なグラフを作成します。ランダムにエッジを削除し始めます。あなたのアイデアはうまくいきますか?(ネタバレ:そうではありません)。

于 2012-11-29T08:59:27.217 に答える
1

私はあなたそれらの線に沿って何かをすることができると思います. ただし、このような構造では、すべてのポインターAが他のすべてのポインターについて認識している必要があります。これによりB、からまたはその逆Bに到達できるようになります。Aこれが、相互接続された少数のポインター以上に拡張できる可能性があるかどうかはわかりません。

プログラマーの助けを借りずに循環参照をサポートしたい場合は、単純な参照カウント方式ではなく、本格的なガベージ コレクターが多かれ少なかれ必要になるようです (これが間違っていることを証明したいと思います)。

于 2012-11-29T08:19:49.187 に答える