2017-03-27 13 views
0

プロジェクトでは、階層レベルを持つグラフを実装するクラス階層があります(グラフノードはグラフ自体になります。例えばゲートが実際に集積チップになることができる回路)。したがって、私はいくつかのクラスBaseGroupLeafに派生させ、クラスBaseGroup(子供を追加する)の所与のメソッドから設定することができますが、ほかの場所からは設定できないようにするためにはancestorという属性を持っています:特定の派生クラスの基底クラスメンバへのアクセスを許可する

class Group; 

class Base { 
    private: // or protected? 
     Group* ancestor; 
}; 

class Group : public Base { 
    private: 
     void setAncestor(Base* child) { 
      // Something like 
      child->ancestor = this; 
     } 
}; 

class Leaf : public Base { 
    // ... 
}; 

これを達成するには "正しい"方法はありますか?通常、私はfriendメソッドを使用しますが、このコンテキストでは不可能であると私には思われます。Baseに友人Group::setAncestorを宣言しなければならないので、前に宣言する必要があります。 (これらの宣言は実際のコードでは異なるファイルにあります)。

+0

これはancestor'が公開されていない限り、 '動作しません。 'Group'は、それ自身の*基本クラスの保護されたメンバーにアクセスできます。これは 'Leaf'のような無関係のクラスの基底であるかもしれないので、' Base'ポインタを通して保護されたメンバにアクセスすることはできません。 –

+1

クラス全体を友人にすることができます。つまり、 'friend class Group;'です。 – songyuanyao

+0

フォワード宣言と 'friend'を使うことができます。 – Raito

答えて

0

データメンバーBase :: ancestorはアクセスを保護する必要があります。そうすれば派生クラスで利用できるようになります。

0

Base、およびLeafクラスで保護されていると宣言できます。保護されているメンバーはプライベートになるため、プライベート継承を使用します。私はchildからnewAncestorに名前を変更

class Group; 

class Base { 
    protected: 
     Group* ancestor; 
}; 

class Group : public Base { 
    private: 
     void setAncestor(Base* newAncestor) { 
      // Something like 
      ancestor = newAncestor->ancestor; 
     } 
}; 

class Leaf : private Base { 
    // ... 
}; 

注意。あなたは新しい子を作成するときに

は、だから、このような何かを行うことができます。

Base ancestor; 
Group child; 
child->setAncestor(&ancestor) 
+0

同じ効果はありません。 –

+0

@O'Neilもちろん、私の例では 'setAncestor()'は別の署名を持っています。ちょうど提案。しかし、私はそれがあなたが言及しているかどうかは分かりません。 – Rama

+0

はい、これです。ポイントは**別の**インスタンスを指し示す '祖先(ancestor) 'を持つことです。 「これ」ではない。 –

関連する問題