0

クラスAのインスタンスが1つあります。オブジェクトAとオブジェクトBの2つのメンバーがあります。オブジェクトA(非常に大きなオブジェクト)のインスタンスを1つ作成し、オブジェクトBのインスタンスを2つ作成してから、オブジェクトBはそのオブジェクトAにアクセスします。オブジェクトAを変更する必要はなく、その情報にアクセスするだけです。

今のところ、オブジェクトAをポインターとして作成し、それをオブジェクトBの両方のインスタンスに渡すことで、すべてが機能するようになりました。オブジェクトBの両方のインスタンスは、オブジェクトAのポインターと同じメモリ内の場所を指す独自のポインターを持っています。これは問題なく動作しますが、それはかなり大きなことだと思います。クラスAが元のポインターを削除すると、ダングリングポインターがいくつかあるので、そうですか?これを行うためのより良い方法はありますか?

(参考までに-オブジェクトAは、高速のロード時間が必要なプログラムで一度にロードするのに数秒かかります。そのため、オブジェクトBに独自のインスタンスを作成させるのではなく、1つのインスタンスのみを作成し、それを両方のオブジェクトBに渡す必要があります。オブジェクトAのインスタンス。)

4

2 に答える 2

2

私があなたを正しくフォローしているなら、あなたはこのようなものが欲しいです:

// Class for "Object A" in your question
class Foo
{
    // ...
};

// Class for "Object B" in your question
class Bar
{
    Foo &foo_;

public:
    Bar(Foo &foo)
        : foo_(foo)
        {}
};

class A
{
    Foo foo_;
    Bar bar1_;
    Bar bar2_;

public:
    A()
        : bar1_(foo_),
          bar2_(foo_)
        {}
};

ポインタや割り当てを使用しないため、ダングリングポインタ/参照やメモリリークは発生しません。破壊されると、も同様にA破壊されるため、の2つのインスタンスにもぶら下がっている参照が残されません。bar1_bar2_foo_Bar

于 2012-09-03T14:05:02.567 に答える
1

「B-things」が「両方がポインタを持つ大きなオブジェクト」よりも長持ちしない場合、「大きなオブジェクト」が削除されたときにダングリングポインタはありません。

「クラスAの1つのインスタンス」に、これらのオブジェクトの両方がデータメンバーとして含まれている場合、それらはすべて同時に破棄されます(クラスで宣言されているのとは逆の順序ですが、ほぼ同時に)。 、したがって、ダングリングポインタが使用されないようにするのはかなり簡単なはずです。

一方、ウィリーニリーの周りの「ビッグオブジェクト」へのポインターを渡す場合は、それらを寿命が不明なさまざまな場所に格納してから、「ビッグオブジェクト」を削除します。確かに、それはノーノーです。問題は「意地悪」です。制御を維持し、大きなオブジェクトがそれを指すオブジェクトよりも長持ちすることを確認する必要があります。

たとえば、次は完全に安全です。

struct Big {
    // big stuff
};

struct Little {
    Little(const Big *a) : bigthing(a) {}
    // stuff that uses bigthing
  private:
    const Big *bigthing;
};

struct Foo {
    Big onlybigthing;
    Little firstlittlething;
    Little secondlittlething;
    Foo() : 
        onlybigthing(), 
        firstlittlething(&onlybigthing), 
        secondlittlething(&onlybigthing) 
    {}
};

もちろん、のインスタンスは、それを要求し、オブジェクトの存続期間を超えてそれを格納する人に、へLittleのポインタを渡さないことを条件とします。同様に、インスタンスのコピーを、それらを格納する可能性のある誰か(およびそれらのポインター)に渡さないようにする必要があります。BigFooFooLittle

しかし、クラスAには2つのメンバーがあると言いますが、ここでは3つ(1つとBig2つLittle)あります。これは、これら2つのオブジェクトの3つのインスタンスを作成すると言うためです。それが何を意味するのかわかりません。

安全なものの別の例を次に示します。

int main() {
    Big big;
    Little little1(&big);
    Little little2(&big);
}

安全なものの3番目の例を次に示します。

struct Little {
    Little(const std::shared_ptr<Big> &a) : bigthing(a) {}
    // stuff that uses bigthing
  private:
    std::shared_ptr<Big> bigthing;
};

int main() {
    std::shared_ptr<Big> big(new Big());
    Little little1(big);
    Little little2(big);
    big.reset(); // release our shared ownership
    // safely do stuff using little1 and little2

    return 0;
    // on exit, little2 is destroyed first, then when little1 is destroyed
    // it releases the last shared ownership of the instance of `Big`,
    // which is destroyed.
}
于 2012-09-03T14:02:32.010 に答える