2012-12-19 4 views
5

は、多くの場合、私は、コードに遭遇しているものそうであれば含まれているクラスへのポインタを渡していますそれを含むクラスから機能... は(コンストラクタで)それ悪いデザインとm_memberがメンバーを呼び出すことができるようにこれが行われる理由</p> <pre><code>/*initializer list of some class*/:m_member(some_param,/* --> */ *this) </code></pre> <p>理由があるようなソリューション

//code in class that is m_member instance of 

    m_parent->some_function(); 

別名、私はそれ哀れなデザイン(「親愛なる子供はあなたがあなたのクラスのカプセル化に何をしている知っています」)考えるので、私は個人的にそれを嫌うが、私は希望知っているように一般的にこの動作が悪いです、もしそうならこの種のデザインを避けてください。

EDIT:このページでは、イニシャライザリストに焦点を当てないでください。

+0

'* this'ではなく' this'を意味するのでしょうか? –

+0

_is_が悪いので、イニシャライザリストで 'this'を使うためのコンパイラ警告(少なくとも)が必要です。しかし、私はこれをたくさん見ていますし、単純な意味で(修正を除いて)それを「修正」する良い方法を考えることはできません。 – Chad

+0

それは意味があるので、refをとる。 Btwはイニシャライザリストにあることを無視します...それはctorボディ内にあると言うことができます。 – NoSenseEtAl

答えて

2

親がリファレンスセットの時間を構成していないので、悲惨なことがあります。

TheChild::TheChild() : 1606422622 
TheParent::TheParent() : 1 

ボトムライン:

#include <iostream> 
using namespace std; 

struct TheParent; 

struct TheChild 
{ 
    TheChild(TheParent& parent); 
    TheParent& myParent; 
}; 

struct TheParent 
{ 
    TheParent() 
     : mychild(*this) 
     , value(1) 
    { 
     cout << "TheParent::TheParent() : " << value << endl; 
    } 

    TheChild mychild; 
    int value; 
}; 

TheChild::TheChild(TheParent& parent) 
    : myParent(parent) 
{ 
    cout << "TheChild::TheChild() : " << myParent.value << endl; 
}; 

int main() 
{ 
    TheParent parent; 
    return 0; 
} 

は明らかに親オブジェクトの不確定な状態に注意して、次の出力を生成します。次の例では、このことを実証する、このようにそれをしません。あなたは良いだろう代わりに、動的割り当てを使用するように役立ったが、それでもこれは警告があります:

#include <iostream> 
using namespace std; 

struct TheParent; 

struct TheChild 
{ 
    TheChild(TheParent& parent); 
    TheParent& myParent; 
}; 

struct TheParent 
{ 
    TheParent() 
     : mychild(NULL) 
     , value(1) 
    { 
     mychild = new TheChild(*this); 
     cout << "TheParent::TheParent() : " << value << endl; 
    } 

    ~TheParent() 
    { 
     delete mychild; 
    } 

    TheChild* mychild; 
    int value; 
}; 

TheChild::TheChild(TheParent& parent) 
    : myParent(parent) 
{ 
    cout << "TheChild::TheChild() : " << myParent.value << endl; 
}; 


int main() 
{ 
    TheParent parent; 
    return 0; 
} 

これは、あなたがそうするために望んでいるものあなたを与える:しかし、

TheChild::TheChild() : 1 
TheParent::TheParent() : 1 

注意、 TheParentが継承チェーンの中間クラスであり、まだ構築されていない派生クラスの関数の潜在的にオーバーライドされた仮想実装にアクセスすることを望んでいる場合、これにも問題があります。

もう一度、あなたがこれをやっていることが分かったら、なぜ最初に必要なのか考えてみてください。

1

プログラミングの慣行の大部分と同様に、それが悪いと言うことは不可能です一般的には(あなたが悪い人であり、恥ずかしいはずです)。私はこれを時々使用しますが、それは珍しいことです。しかし、クラスデザインを変更して意図的に避けようとすることはありません。

上記の段落で「私」を多少使用したことに注意してください。これは非常に主観的な問題です。

2

親クラスがm_memberがどのように構築されているかが不明であるため、悪いです。例えば

:メンバーは、コンストラクタの本体にいわゆる「のsetParent」メソッドを持っているため

class Parent 
{ 
    Parent() 
    : m_member(this), m_other(foo) 
    { } 
}; 

class Member 
{ 
    Member(Parent* parent) 
    { 
     std::cout << parent->m_other << std::endl; // What should this print? 
    } 
}; 

わずかに良いアプローチ親ポインタが必要な場合があります。

+0

ああ - OK、悪いことがあります。私は、privateメンバーを後で使用するように設定するためにのみ使用します。含まれるクラスctor内の親呼び出しでは使用しません。 –

+0

実際、親クラスがどのくらい完全であるかは不明ですが、コード自体が不完全であるためです。 'Parent'コンストラクタと' Member'コンストラクタへの引数として 'Parent'ポインタを使用する間に明白な接続はありません。私は、実際のコードでこの答えを始める主張が間違っていると考えています。 –

+0

それはいつもクラッシュするので悪くないです(私はそれがいつもコンパイルされるとは確信していませんが)。それはメンバークラスでParentの前提が作られなくてはならず、とても面倒です。 – amaprotu

0

特定の問題の解決方法を実装するツールとして、この言語が表示されています。設計上、C++はthisと他のオブジェクト指向言語を明示的に使用することはできません。したがって、私はツールボックス内のツールとして言語機能を見ていますが、たいてい1つのツールまたは他のツールを使用することがあります。

しかし

、それはコーディングスタイルと実践が入ってくるところ、私は私がやっているかを知る必要があります。ツールの使い方を知っておく必要があります。その使用の意味を理解する必要があります。 C++が新しいオブジェクトを初期化する定義された順序があり、私がで作業している限り、これは良いことです。残念ながら、人々は何度か幸運になる。それ以外の時には、彼らはそのようにバグを作ります。あなたは、あなたのツールを知っておく必要があり、どのように私の個人的な意見であなたの質問に答えるために

:-)それらを使用する:私は、この特定の構造物を回避しようと、しかし機会に、私はそれを使用する必要がありました。クラスの再設計を熟考しても、それを回避することはできませんでした。そして、私はこの機会を「ああ、時には私のデザインがきれいで清潔なストレートオブジェクト指向でモデル化できないことがあります。クラス間の依存関係があまりにも厳しく、パフォーマンスが重大です。

+0

C++だけでなく、Delphiには 'this'と同じものがあります。 –

関連する問題

 関連する問題