2017-07-28 10 views
0

J'ai rencontré le problème suivant et je ne sais pas vraiment quelle est la meilleure façon d'aborder cela. Je veux évaluer expression objets qui sont construits avec un objet foo. La classe expression et ses classes dérivées doivent pouvoir accéder aux membres privés de foo; mais excepté de déclarer toutes les classes dérivées individuellement comme ami je ne sais pas comment je pourrais faire ce travail - puis-je déclarer une fonction virtuelle un ami de foo?Statut d'ami pour les classes dérivées de classe purement virtuelle

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; 
}; 

Les expression classes:

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; 
    } 
}; 

La fonction 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; 
} 

Ce code ne fonctionne pas bien sûr, mais je ne veux vraiment pas ajouter chaque classe dérivée de expression en tant qu'ami ou marque expression hériter de foo. Y a-t-il une autre solution?

+1

L'utilisation d'une fonction get? – Jonas

+0

Oui cela fonctionnerait - je pourrais également rendre tous les membres publics mais ce n'est pas le point. D'une certaine manière, je veux que l'objet 'foo' prenne possession des objets' expression' et je ne veux pas exposer les membres de 'foo' directement ou par l'intermédiaire de get-functions. –

+0

Vous pourriez rendre 'expression' une classe d'amis de' foo', et implémenter get-functions dans 'expression'. – Jonas

Répondre

0

Je voudrais faire expression une classe d'ami de foo, qui est, ajouter ce qui suit à foo:

friend struct expression; 

Et puis mettre en œuvre get-fonctions expression, comme ceci:

struct expression { 
// other stuff 

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

Le get-functions doit être marqué protected pour réduire l'exposition. Le paramètre de la fonction get est const, pour faire bonne mesure.

+0

pourquoi pas simplement 'foo :: get_a()'? – user463035818

+0

@ tobi303 Tout simplement parce que OP ne l'a pas aimé ... parce qu'il a exposé certains des membres de foo. Mais oui, cela semblait être la solution rapide. – Jonas

+0

ah désolé n'a pas vu le commentaire qui dit 'foo :: get' n'est pas une option – user463035818