2017-07-28 11 views
0

次の問題が発生しましたが、これに最も良い方法が何であるかはわかりません。 fooオブジェクトで構築されたexpressionオブジェクトを評価したいと思います。 expressionクラスとその派生クラスはfooのプライベートメンバーにアクセスできるようにする必要があります。派生したすべてのクラスを個別に宣言することを除いて、友人として私はこの仕事をどうすればできるのか分かりません。fooの仮想関数を宣言できますか?純粋に仮想クラスの派生クラスのフレンドステータス

class foo{ 
public: 
      foo(int a, int b, int c) : a(a), b(b), c(c) {} 
    void addExpression(expression *e){exp.push_back(e);} 
    bool evaluateAll(){ 
     for(expression* e : exp){ 
      if(!e->evaluate()) 
       return false; 
     } 
     return true; 
    } 
private: 
    int a,b,c; 
    std::list<expression*> exp; 
}; 

expressionクラス:

struct expression{ 
    expression(foo *f) : f(f) {} 
    virtual bool evaluate() = 0; 
private: 
    foo *f; 
}; 

struct anExpression : public expression{ 
    anExpression(foo *f) : expression(f) {} 
    bool evaluate(){ 
     return f->a < f->b; 
    } 
}; 

struct anotherExpression : public expression{ 
    anotherExpression(foo *f) : expression(f) {} 
    bool evaluate(){ 
     return f->a > f->b && f->a != f->c; 
    } 
}; 

main機能:

int main(int argc, char *argv[]){ 
    foo f(3,2,1); 
    f.addExpression(new anExpression(&f)); 
    f.addExpression(new anotherExpression(&f)); 
    f.evaluateAll(); 

    return 0; 
} 

このコードはもちろん動作しませんが、私は本当にのすべての派生クラスを追加する必要はありませんexpressionを友人にするかexpressionfooから継承してください。別の解決策がありますか?

+1

get-functionを使用しますか? – Jonas

+0

はい、それはうまくいく - 私もすべてのメンバーを公開することができますが、それはポイントではありません。ある意味では、 'foo'オブジェクトが' expression'オブジェクトを所有することを望み、 'foo'のメンバーを直接またはget関数を介して公開したくありません。 –

+0

'expression'を' foo'のfriendクラスにし、 'expression'にget-functionsを実装することができます。 – Jonas

答えて

0

私はFOOに以下を追加し、つまり、fooexpressionフレンドクラスになるだろう。そして、

friend struct expression; 

そしてそのように、expressionで取得-関数を実装:

struct expression { 
// other stuff 

protected: 
    int get_a(foo const * f) { return f->a; } 
} 

get-functionsは、露出を減らすためにprotectedとマークする必要があります。良い関数のために、get関数のパラメータはconstです。

+0

単に 'foo :: get_a()'ではないのですか? – user463035818

+0

@ tobi303 OPがそれを気に入らなかったのは単にfooのメンバーの一部を公開したからです。しかし、はい、それは迅速な解決策のように思えました。 – Jonas

+0

ああ、申し訳ありませんでしたが、 'foo :: get'はオプションではないというコメントが表示されます – user463035818

関連する問題