OOP - composition

I'm following learncpp tutorial(http://www.learncpp.com/cpp-tutorial/102-composition/) and linked chapter I see overloaded operator<< being completely defined inside class(and is also friend function), which is different than what overoading chapter ws learning(do friend declaration in class, but define it outside class). Is this standard practice for composition or is there any trick to define it outside class?
Last edited on
closed account (48T7M4Gy)
It's to do with the stream and this isn't a bad rendition of why friend etc

https://stackoverflow.com/questions/236801/should-operator-be-implemented-as-a-friend-or-as-a-member-function
There are three possibilities:

a. The friend declaration in the class body and the function defined at namespace scope outside the class.
(my::foo in the following example)

b. The friend function defined in the class body and the function not declared outside the class at enclosing namespace scope. (my::bar in the following example)

c. The friend function defined in the class body and the function also declared outside the class at enclosing namespace scope. (my::foobar in the following example)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>

#ifdef _MSC_VER
    #define NAME_OF_THIS_FUNCTION __FUNCSIG__ // Microsoft
#elif defined __GNUG__
    #define NAME_OF_THIS_FUNCTION __PRETTY_FUNCTION__ // GNU or compatible
#else
    #define NAME_OF_THIS_FUNCTION __func__ // fall back to standard C++
#endif // _MSC

namespace my
{
    struct A
    {
        friend void foo( A& a ) ; // friend declaration in the class body

        friend void bar( A& a ) // friend defined within the class body; and not declared at namespace scope
                                // a. the function is not a member function of this class
                                // b. the function is impliciltly inline
                                // c. the function is a member of the enclosing namespace of A
                                //                             (in this case the namespace my)
                                // d. however, its name won't be found via normal name look up
                                // e. however, the function can be found via ADL (argument-dependent lookup aka koenig lookup)
        {
            a.v += 7 ;
            std::cout << NAME_OF_THIS_FUNCTION << " is a friend of A\n" ;
        }


        friend void foobar( A& a ) // friend defined within the class body; and declared at namespace scope
                                   // a. the function is not a member function of this class
                                   // b. the function is impliciltly inline
                                   // c. the function is a member of the enclosing namespace of A
                                   // d. like foo, and unlike bar, its name can be found via normal name look up
        {
            a.v += 7 ;
            std::cout << NAME_OF_THIS_FUNCTION << " is a friend of A\n" ;
        }


        private: int v = 0 ;
    };

    void foo( A& a ) // friend function defined in the enclosing namespace
                     // foo is a normal function which is at namespace scope
    {
        a.v += 7 ;
        std::cout << NAME_OF_THIS_FUNCTION << " is a friend of A\n" ;
    }

    void foobar( A& a ) ; // friend function declared in the enclosing namespace
}

int main()
{
    my::A a ;

    foo(a) ; // fine: prints 'void my::foo(my::A&) is a friend of A'
    my::foo(a) ; // also fine: prints 'void my::foo(my::A&) is a friend of A'

    bar(a) ; // fine, name found via ADL prints 'void my::bar(my::A&) is a friend of A'
             // (this is the only way in which the name my::bar can be found)

    // my::bar(a) ; // *** error: name my::bar not found

    // my::A::bar(a) ; // *** error: bar is not a member of my::A

    foobar(a) ; // fine: prints 'void my::foobor(my::A&) is a friend of A'
    my::foobar(a) ; // also fine: prints 'void my::foobar(my::A&) is a friend of A'
}

http://coliru.stacked-crooked.com/a/04753552ec504390
http://rextester.com/IAL62835
Topic archived. No new replies allowed.