2

具体的な問題:

タイプ A とタイプ B (他のタイプの中でも) のオブジェクトを持つメイン アプリケーションがあります。タイプ B のオブジェクトは、A オブジェクトを適切に構築する必要があります (したがって、コンストラクター A(const B& b) があります。ただし、Main は保持している B オブジェクトをいつでも変更できます。Main がその B オブジェクトを変更したときに、オブジェクトの内部参照が変更されましたか?

一般に、オブジェクトに依存関係がある場合、オブジェクトの有効期間を管理するための良い方法は何ですか?

4

6 に答える 6

3

Aどのプロパティもキャッシュせず、依存する出力を生成するために保持するBインスタンスを常に参照する場合、に対して行われた変更は、以降の への呼び出しに反映される必要があります。コンストラクター内に参照を格納しているだけで、ローカル コピーを作成していないと仮定しています。BBAB

于 2011-07-18T15:55:35.507 に答える
1

私の理解が正しければ、B オブジェクトを変更するだけでなく、別の B に完全に置き換える必要があります。一度作成した参照は変更できないため、代わりにポインターを使用する必要があります。

Observer パターンを使用して、A オブジェクトに B をいつ置き換える必要があるかを知らせることができます: http://en.wikipedia.org/wiki/Observer_pattern

于 2011-07-18T16:08:39.127 に答える
0

これが私が問題を処理した方法です。ユーザーコードは次のようになります。

class Env
{
public:
   Env();
   ~Env();
private:
   void *priv;
};
class MyInterface
{
 public:
  MyInterface(Env &e) : e(e) { }
  int create_A();
  void use_A(int a);
 private:
   Env &e;
   void *priv; 
 };
 int main()
 { 
    Env e;
    MyInterface i(e);
    int a = i.create_A();
    use_A(a);
 }

このようにして、すべての依存関係がユーザーコードに表示されます。オブジェクト間の依存関係は、Envクラスのstd::vectors内に適切に保存されます。ベクトルへのインデックスは関数から返されます。create_A()とuse_A()は、intを介して通信できます。Envクラスがスコープから外れると、オブジェクトはすべて同時に破棄されます。オブジェクトは、仮想デストラクタを持つ基本クラスから派生している可能性があります。

複数のintがある場合、推奨される方法は次のとおりです。

struct ID { int i; };

インターフェイスの実装は、次の機能に依存します。

A *find_a(const Env &e, ID i);
ID create_a(Env &e, A *ptr);

上記のアプローチは、オブジェクトの存続期間に関する次の問題を解決します。

  1. オブジェクトの寿命
  2. オブジェクト間の依存関係(int経由)
  3. オブジェクトの識別
  4. 依存関係は、intまたはポインターを介して格納できます。
  5. 寿命が終わったときにオブジェクトを破壊する
于 2011-07-18T16:02:43.537 に答える
0

次の点に注意してください。

  1. すべての問題は、もう 1 層の間接化で解決できます。
  2. オブジェクトの所有権は明らかでなければなりません。

あなたの場合、Bインスタンスがいつでも行き来できる場合(古いインスタンスが削除され、新しいインスタンスが「新しく」なる)、Bインスタンスを「ラップ」する「ユーティリティハンドル」クラスを作成できます。

class BHandle {
  B* b_; // can change at any time
  public:
    ....
};

次に、Aクラスはインスタンスを参照するBHandleか、インスタンスを完全に含みBHandleます。その後、Bインスタンスは行き来できますA::my_b_handle_が、「現在の」Bインスタンスがどこにあるかを常に反映します。

一方、Bインスタンスに変更されるデータ メンバーがあるだけの場合 (そのインスタンス自体は行き来しない)、何もする必要はありません (Aは常に同じBインスタンスを参照し、場合によっては参照するオブジェクトでAプロパティが変更されたことを「通知」する必要があるだけです)。B

于 2011-07-18T16:01:02.377 に答える
0

一般的に: 常に所有権について知っていることを確認してください。オブジェクトを作成するときはいつでも、別のオブジェクトが所有者であるか、ローカル変数である必要があります。あなたの場合、メイン ルーチンは B へのインスタンスの所有者になります。A インスタンスに B への参照がある場合、A はインスタンスへのすべての変更を確認します。コピーしないようにしてください (参照がない場合は暗黙のコピー)。したがって、コードには次のようなものがあります

private:
  const B& theReference;

また

private:
  B& theReference;

const 以外のメソッドを呼び出す必要がある場合 (その場合は、コンストラクターも変更することを忘れないでください)。

于 2011-07-18T15:55:51.543 に答える
0

私があなたを正しく理解していれば、main が保持するオブジェクトに変更を加えた場合、保持されているオブジェクトに影響を与えるはずAです。これには、コンストラクター初期化子の助けを借りることができます。

#include <iostream>

class B{
    public:
        int num ;
        B(int arg):num(arg) {}
};

class A{
    public:
        const B& ref ;
        A( const B& arg ): ref(arg){}
};

int main()
{
        B objOne(10) ;
        A objTwo(objOne) ;

        std::cout << objTwo.ref.num << std::endl ;
        objOne.num = 20 ;
        std::cout << objTwo.ref.num << std::endl ;
}

出力:

10
20

于 2011-07-18T15:59:29.417 に答える