2

I have a class that represents a special number.

class SecretInteger
{
private:
    unsigned int *data;
    size_t length;

public: 
    SecretInteger operator+(const SecretInteger other) const;
}

I can't allow any other part of my code have access to the data variable. However, my operator+ function MUST be able to see it. Usually in this case I know that using the friend keyword is the only way to do it. However when I write:

friend SecretInteger operator+(const SecretInteger other);

It claims that the operator+ cannot be declared as friend, even though I've previously wrote friend std::ostream& operator<<(std::ostream& stream, const SecretInteger val); and it works fine.

What options do I have available to me? If I have a public method like

const *unsigned int getData() const; I think even then it doesn't actually make the variable returned const right? I'd really prefer not to have a getData() method and instead just declare the functions that have access as friend.

Ken White
  • 123,280
  • 14
  • 225
  • 444
Hatefiend
  • 3,416
  • 6
  • 33
  • 74
  • You're declaring `operator+` as a member function so it could access `data`, isn't it? – songyuanyao Feb 09 '17 at 03:06
  • ~~It cannot access `other`'s data which makes it impossible for me to perform arithmetic.~~ – Hatefiend Feb 09 '17 at 03:08
  • Side-note: Even if you insist on a member function for the overload, there is no reason to accept the argument by value. Surely `const SecretInteger& other` is what you want. – ShadowRanger Feb 09 '17 at 03:10
  • @ShadowRanger why is it bad to make the operator overload a member function? What's the alternative? If you mean making a friend function, it doesn't allow me to do that. Also `SecretInteger` is an immutable class so I thought pass by value is totally okay as I don't plan on making any changes to `other` at any point. – Hatefiend Feb 09 '17 at 03:12
  • @Hatefiend No, it can. Did you try with it? – songyuanyao Feb 09 '17 at 03:14
  • @Hatefiend: If you don't plan on making any changes, but accept the argument by value, then you're pointlessly constructing new copies. A const reference means you avoid constructing anything, using a reference to the existing instance instead of reconstructing (and destroying later), saving a bunch of pointless work. As for avoiding member functions for non-in-place overloads, that's [been covered at great length](http://stackoverflow.com/q/4622330/364696); I won't recapitulate it. – ShadowRanger Feb 09 '17 at 03:18

1 Answers1

4

You don't declare a member function as a friend, friend is to give non-member functions access to internals, and a one operand overload of operator+ is a member function.

In any event, if you implement the binary operators properly, you shouldn't need to give out friendship at all. Implement += as a member function (no need for friend, a class is always "friends" with itself), then implement a non-member + operator in terms of +=, which uses +='s access to the internals to avoid the whole issue of friendship.

The basic rules for overloading can be found here and should help a lot.

Community
  • 1
  • 1
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Wait.... why does my program have access to `other`'s internals? In Java this would not be the case. What's going on here? In my `operator+` I am able to access private member `data` of both `this` and `other`. Why? – Hatefiend Feb 09 '17 at 03:09
  • Oh so if you have `class A` and ANY function in `A` that takes in a parameter of type `A`, it will have private access to that variable? – Hatefiend Feb 09 '17 at 03:13
  • 1
    @Hatefiend: [Java gives you access too](http://stackoverflow.com/a/29068196/364696). `private` means "only accessible to this class", so any `SecretInteger` can access the `private`s of any `Secretinteger`, itself or a different instance. `private` is for interface purposes, it's not a security feature to firewall instances from one another. – ShadowRanger Feb 09 '17 at 03:14