2011-07-08 3 views
1

現在のオブジェクトが他の含まれているオブジェクトによって操作されているシステムで、現在のオブジェクトへの参照が渡されると、リンクは何も終了せずに続きます(下のコードの場合はCar->myCurrentComponent->myCar_Brake->myCurrentComponent->myCar_Brake->myCurrentComponent .... )。ポインタ参照パターン - よく使用されますか?

I CarおよびCar->myCurrentComponent->myCar_Brakeは同じアドレスを参照し、同じオブジェクトを指します。それは車の中にCarを含むBrakeが入っているようなものです。

実際、Carは唯一のオブジェクトです。myCar_BrakeとmyCar_Speedはそれを参照します(参照)。このような参照とポインタの使用は通常ですか?このアプローチに潜在的な問題はありますか?

サンプルコード

あなたはそれを理解しての追跡をすることなく、あなたのオブジェクトグラフをトラバースしようとしない限り、あなたのオブジェクトグラフ内の循環参照を持つ根本的な問題はありません
class Brake 
class C 

class Car 
{ 

public: 

Car(); 
// Objects of type B and C. 
Brake* myBrake; 
Speed* mySpeed; 

// Current component under action. 

Component* myCurrentComponent; 

} 
/******************************/ 
// Constructor 

Car::Car() 
{ 
myBrake = new Brake(*this); 
mySpeed = new Speed(*this); 

myCurrentComponent = myBrake; 
} 

/******************************/ 
class Brake: public Component 
{ 

public: 

Brake(Car&); 
// Needs to operate on A. 
Car* myCar_Brake; 

} 

// Constructor 
Brake::Brake(Car&) 
{ 
myCar_Brake = Car; 
} 

/******************************/ 
class Speed 
{ 

public: 

Speed(Car&); 

// Needs to operate on A. 
Car* myCar_Speed; 

} 

// Constructor 
Speed::Speed(Car&) 
{ 
myCar_Speed = Car; 
} 

/****************************/ 
+0

ブレーキとスピードが多態性でない限り、ポインタは必要ありません。代わりにオブジェクトを使用します。 –

+0

申し訳ありません.....示されていませんが、あなたが指摘したように、それらは多型です。 – First

答えて

5

あなたが遭遇したオブジェクト。あなたの質問に具体的に答えるには、オブジェクト間の循環参照が比較的一般的です。例えば、二重リンクリストが動作する方法です。

+0

真実ですが、二重リンクリスト(またはその点については単一のリスト)は、OPの例に基づいて実生活オブジェクトをモデリングするとき、非常に珍しい構造です。 –

+0

@CaptainGiraffe:それはすべてモデリングに依存します。共通の現実世界の例:人は親戚を持っています。その親族の間には親子と子どもがいます。 –

+0

それは標準的な反例になります。それでも私は、そのデザインが必要であることは珍しいと主張するだろう。 –

0

ポールが言及しているように、循環参照に問題はありませんが、上記のコード例はカプセル化が完全に行なわれておらず、メモリリークの問題もありません。

このようなことを許可することは理にかなっていますか?

Speed::Speed(Car& value) 
{ 
    myCar_Speed = value; 
    // WTF code below 
    value->myCurrentComponent->myCar_Brake = NULL; 
} 

また、

Car::Car() 
{ 
    myBrake = new Brake(*this); 
    mySpeed = new Speed(*this); 
    //if Speed::Speed(Car&) throws an exception, memory allocated for myBrake will leak 
    myCurrentComponent = myBrake; 
} 

は、リソースマネージャのいくつかの種類せずに生のポインタを使用しないでください。

0

CarBreakSpeedの関係の実際のオブジェクト構造の妥当性を議論しないと、このアプローチは、1つのマイナーな問題があります。それは、無効な状態にすることができます。

場合 - 何かが - うまくいかない、それはCarインスタンス#1はCarインスタンス#3に属しBreakインスタンス#2を持っていることを、この設定で可能です。二重リンクリストの一般的な問題 - アーキテクチャ自体が無効状態を有効にします。もちろん、慎重な可視性変更子の選択と機能の優れた実装は、それが起こらないことを保証することができます。それが完了して安全なときには、修正をやめ、「ブラックボックス」として使用し、それを使用するだけで、それをねじ込む可能性は排除されます。

しかし、個人的には、高水準の、常に維持されているコードに対して無効な状態を許可するアーキテクチャを避けることをおすすめします。二重リンクされたリストは、これまでのようにコードの変更をほとんど必要としない低レベルのbalckボックスコードです。あなたはCarBreakSpeedについてあなたは言うことができますか? Carが自分は「Carを所有している」のか分からないでしょうBreakSpeed、およびBreakSpeedを持っていた場合

、作成し、無効な状態にすることは不可能だろう。もちろん、それは具体的な状況に合わないかもしれません。

+0

また、この特定のセットアップでは、「Break and Speed」からの後方リンクを削除します。スピードはそれを持っている車について知る必要はありません。 Breakには、doBreaking(const Car onThisCar、Speed&currentSpeed)関数が必要です。すべてのブレーキが「特定の車の速度を操作する」とは、「車を持っていて速度を操作することはできません」ではなく、 –

関連する問題