2017-07-28 211 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或從foo繼承expression。還有其他解決方案嗎?

+1

使用獲取函數? – Jonas

+0

是的,這將工作 - 我也可以讓所有的成員公開,但這不是重點。在某種程度上,我希望'foo'對象擁有'expression'對象,並且我不想直接或通過get函數暴露'foo'的成員。 –

+0

你可以使'expression'成爲'foo'的一個好友類,並在'expression'中實現get-function。 – Jonas

回答

0

我會做expression朋友類foo,即,添加以下爲foo:

friend struct expression; 

,然後實現獲得-功能expression,像這樣:

struct expression { 
// other stuff 

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

的獲取函數應該標記爲protected以減少暴露。獲得函數的參數是const,這是一個很好的衡量標準。

+0

爲什麼不簡單地使用'foo :: get_a()'? – user463035818

+0

@ tobi303只是因爲OP不喜歡它......因爲它暴露了foo的一些成員。但是,是的,這似乎是快速解決方案。 – Jonas

+0

啊對不起,沒有看到'foo :: get'不是一個選項的評論 – user463035818