0

I ran into the following problem and I don't really know what the best way is to approach this. I want to evaluate expression objects that are constructed with a foo object. The expression class and its derived classes should be allowed to access private members of foo; but except from declaring all derived classes individually as friend I don't know how I could make this work - can I declare a virtual function a friend of 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;
};

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

The mainfunction:

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

This code doesn't work of course but I really don't want to add every derived class of expression as a friend or make expression inherit from foo. Is there another solution?

Ganymed_
  • 13
  • 4
  • 1
    Using a get-function? – Jonas Jul 28 '17 at 20:49
  • Yes that would work - I also could make all the members public but that's not the point. In a way I want the `foo` object to take possession of the `expression` objects and I don't want to expose the members of `foo` either directly or via get-functions. – Ganymed_ Jul 28 '17 at 20:53
  • You could make `expression` a friend class of `foo`, and implement get-functions in `expression`. – Jonas Jul 28 '17 at 20:57
  • 1
    What I would do is to make `expression` a friend of `foo` and have a `protected` function inside `expression` which gets values from `foo`. – SergeyA Jul 28 '17 at 21:00
  • That is definitely a better solution but I would still have to change the `expression` class every time I change `foo` - is that really the best solution? – Ganymed_ Jul 28 '17 at 21:10

2 Answers2

0

I would make expression a friend class of foo, that is, add the following to foo:

friend struct expression;

And then implement get-functions in expression, like so:

struct expression {
// other stuff

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

The get-functions should be marked protected to reduce exposure. The parameter of the get-function is const, for good measure.

Jonas
  • 6,915
  • 8
  • 35
  • 53
0

I may be wrong but isn't this a case for the Curiously recurring template pattern? https://en.m.wikipedia.org/wiki/Curiously_recurring_template_pattern

Treebeard
  • 322
  • 1
  • 9