0

I have the following class:

class PhoneCall{
private:
    string number;
public:
    /*some code here */
};

Now, I have declared a function (not friend to PhoneCall) which does some specific operation and returns a PhoneCall object

PhoneCall callOperation()

Another which takes a PhoneCall object as parameter

void userCall(PhoneCall obj)

I was expecting it not to work unless it is explicity declared as a friend to that class.

Why and how do these functions work even when they are not friend to the PhoneCall class ?

A friend function of a class is defined outside that class' scope but it has the right to access all private and protected members of the class http://www.tutorialspoint.com/cplusplus/cpp_friend_functions.htm

Abrar
  • 6,874
  • 9
  • 28
  • 41
  • In your opinion: which private or protected member of PhoneCall does `userCall()` requires? – fukanchik Nov 07 '15 at 22:15
  • 1
    If instead of `PhoneCall` you were to declare those function with the `std::string` type, would you need the functions to be friends with `std::string`? – William Nov 07 '15 at 22:15
  • 3
    `A friend function of a class is defined outside that class' scope but it has the right to access all private and protected members of the class`. It doesn't say a non-friend function can't return or take as parameter an object of that class. – 101010 Nov 07 '15 at 22:16
  • as declared in the prototype , `userCall()` access the member `string number` via setter @fukanchik – Abrar Nov 07 '15 at 22:18
  • 1
    @AbrarShariarGalib Oh, really? And which part of this prototype declares this? – Mateusz Grzejek Nov 07 '15 at 22:30

1 Answers1

5

You can pass, manipulate and return instances of a class without beeing its friend, as long as you do not access its private or protected members.

According to N4296. p. 261:

11.3 Friends

A friend of a class is a function or class that is given permission to use the private and protected member names from the class.

Unless you declare your move or copy constructors as private or protected, the object can be also copied or moved as a whole.

So practically a private PhoneCall constructor will prevent non-friends from instantiating PhoneCall objects:

For example:

class PhoneCall{
    private: PhoneCall(){}
};

This prevents non-friend code from instantiating the class:

PhoneCall callOperation(){
    return PhoneCall();
}

will results in a compile-time error:

error: 'PhoneCall::PhoneCall()' is private

Edit: Added info on private constructors following M.M`s suggestion in the comments.

Community
  • 1
  • 1
oo_miguel
  • 2,374
  • 18
  • 30
  • Maybe OP is overlooking the point that it is the **member names** which may not be used inside the non-friend code. The object may still be copied as a whole, or have those members accessed in other ways which don't involve the name appearing. – M.M Nov 07 '15 at 22:43
  • @M.M Thanks for pointing this out. I just added a sentence about constructors. – oo_miguel Nov 07 '15 at 22:47