0
#include <memory>

struct B;    

struct A
{
     std::shared_ptr<B> field1_;
     A():field1_ (std::make_shared<B>()){}
};

template<class A>
struct B: std::enable_shared_from_this<B<A>>
{
     A *field1_; 

     void stop()
     {
        delete field1_; //~= delete this
     }

     A* start()
     {
         field1_ = new A(shared_from_this());
         return field1_;
     }
};

int main()
{
    A * reftoA = nullptr;

    {
        std::shared_ptr<B<A>> b = std::make_shared<B<A>>();
        reftoA = b->start();
    }

    reftoAa->field1_->stop();
}

本番環境にバグがあり、上記のコードが HEAP を破損したり、未定義の動作につながる可能性があるかどうか疑問に思っています。

編集: 上記のコードを変更して、実際のコードに近づけました。

4

3 に答える 3

2

独自のメソッドの 1 つからオブジェクトを削除することは、慎重に慎重に行う場合、非常に一般的な手法です。COM や Mozilla コードベースのような派生物など、多くの古い参照カウント設計はそのように機能します。アドバイスについては、 http : //www.parashift.com/c++-faq-lite/delete-this.htmlを参照してください。

しかし、この場合は、一種の偶発的なエイリアシングのように見えます。StructBは、部分的に のオブジェクトの「所有者」のように振る舞うように見えるため、オブジェクトfield1_を削除する権利を与えます。

これは C++ であるため、完全なプログラムのソースを見ないと、これが未定義の動作につながるかどうかを実際に判断することはできません。

于 2012-11-05T10:01:10.823 に答える
2

そのコードはコンパイルするべきではありません。

void setA(A* a):field1_(a){}

これは有効ではありません。

また、すでにスマート ポインターを使用しているのに、そのままにしておく必要A *field1_;はありBません。

于 2012-11-05T09:54:33.917 に答える
0

このような製品コードには死刑を科すべきです。

あなたはそれがポインタを保持しているB::funcを破壊することを呼び出してから、あなたは再び削除します。何を期待していましたか?AmainA

于 2012-11-05T10:30:01.497 に答える