0

This is what I am trying to do. I'm trying to add each member of f1 and f2 together. _m is the slope and _b is the y-intersept.

linear_function operator +
        (const linear_function& f1, const linear_function& f2)
    {
        linear_function f;

        f._m = f1._m + f2._m;
        f._b = f1._b + f2._b;

        return f;
    }

But it says that the members are inaccessible. Here is the .h file.

#ifndef LINEAR_H
#define LINEAR_H
#include <iostream>  // Provides ostream

namespace main_savitch_2
{

    class linear_function
    {
    public:
        // CONSTRUCTOR
        linear_function(double _b = 0.0, double _m = 0.0);
        // MODIFICATION MEMBER FUNCTIONS
        void set(double _b, double _m);
        // CONSTANT MEMBER FUNCTIONS
        double eval(double x) const;
        double root() const;
        double slope() const;
        double y_intersept() const;
        // CONSTANT OPERATORS
        double operator ( ) (double x) const;
    private:
        double _m, _b;
    };

    // NON-MEMBER BINARY OPERATORS
    linear_function operator +
        (const linear_function& f1, const linear_function& f2);
    linear_function operator -
        (const linear_function& f1, const linear_function& f2);
    linear_function operator |
        (const linear_function& f1, const linear_function& f2);

    // NON-MEMBER OUTPUT FUNCTIONS
    std::ostream& operator << (std::ostream& out, const linear_function& p);

}
#endif

I googled member vs nonmember operator overloading and made mine match what was shown. Not sure why I'm getting this error.

Canefan23
  • 1
  • 2
  • If you stick with this approach then make sure that your function bodies are also inside `namespace main_savitch_2` ! Because `::operator+` is a different function to `main_savitch_2::operator+` . – M.M Sep 09 '14 at 04:36

4 Answers4

2

Since members _m and _b are private, only members of the class and their friend functions are allowed to access them. In order to give outside functions access to members, you need to add friend keyword to operators' declarations inside the class, like this:

friend linear_function operator |
    (const linear_function& f1, const linear_function& f2);
friend linear_function operator -
    (const linear_function& f1, const linear_function& f2);
friend linear_function operator |
    (const linear_function& f1, const linear_function& f2);
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

Perhaps friend is your friend. Try to declare operators as friend functions within your class in order to provide access to class private members.

class linear_function
{
    ....

    friend linear_function operator +
        (const linear_function& f1, const linear_function& f2);
    friend linear_function operator -
        (const linear_function& f1, const linear_function& f2);
    friend linear_function operator |
        (const linear_function& f1, const linear_function& f2);
}
AlexD
  • 32,156
  • 3
  • 71
  • 65
0

A better option than using friend (especially if you wanted these operators anyway) is to use member assignment operators:

class linear_function
{
    // ...

    linear_function & operator+= (linear_function const &f)
    {
        _m += f._m;
        _b += f._b;
        return *this;
    }
};

// non-member but does not need special access rules now
linear_function operator+ (linear_function f1, linear_function const &f2)
{
    return f1 += f2;
}

Update: Included sample implementation of member operator+=. Normally I'd declare this in-line and put the definition in the .cpp file, but have shown the definition in-line here to keep the example simple.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • I was going to upvote this, then realized that you were altering `this`. Overload `operator +=` for that, and make `operator +` const and return a temp. – Wug Sep 09 '14 at 03:58
  • @Wug I'm not sure what you are trying to say. `operator+=` should alter `*this` because it means to assign to the current object. Altering `this` is not possible. I don't know what you mean by "make operator+ const". Non-member functions cannot be `const`. I don't know what you mean by "return a temp". – M.M Sep 09 '14 at 04:01
  • @Wug anyway, updated my post to show a sample implementation of `operator+=`, hopefully it is clearer now – M.M Sep 09 '14 at 04:03
  • @Wug OK, your answer has member `operator+`, mine has non-member. As far as I'm aware, member `operator+` is considered bad style. If a function does not use `*this` at all then it does not make sense for it to be a non-static member. – M.M Sep 09 '14 at 04:38
  • It does use `this`, implicitly (via `_b` and `_m`). And I have never seen anything that would indicate a member `operator+` is bad practice. One thing that is definitely bad practice though is modifying arguments in an `operator+`. The rule I've always heard and followed is when overloading operators, make their behavior analogous to operators on primitive types. Your example would be like adding 1 + 2 and changing the value of 1 to 3, and is exactly how `operator +=` behaves when applied to other types (including your own class-member example). – Wug Sep 09 '14 at 04:46
  • OK, my last comment was bogus. But [see here](http://stackoverflow.com/questions/4622330/operator-overloading-member-function-vs-non-member-function) for discussion of why non-member `operator+` is preferred. I think you misread my example, IDK how you think that `1 + 2` would change the value of `1`. `f1` is passed by value, changes to `f1` do not affect whatever argument was passed by the caller of `operator+`. – M.M Sep 09 '14 at 04:50
  • You're right, I didn't notice that `f1` wasn't passed by reference. And that answer isn't really relevant unless you're dealing with operators that take different types of arguments, the example he provides shows a member `Sample::operator+(const Sample &other)`. – Wug Sep 12 '14 at 21:13
  • @Wug I'm suggesting an improvement – M.M Sep 12 '14 at 23:26
0

Consider something like this:

class linear_function
{
public:
    ...

    linear_function operator+(const linear_function &other) const
    {
        return linear_function(_b + other._b, _m + other._m);
    }
};

If you're unable to modify the definition of this class, just keep the out-of-class definition you have and use the getters linear_function::slope() and linear_function::y_intercept(), which fetch the values of _m and _b:

linear_function operator+(const linear_function &l, const linear_function &r)
{
    return linear_function(l.y_intercept() + r.y_intercept(),
                           l.slope() + r.slope());
}
Wug
  • 12,956
  • 4
  • 34
  • 54