Importance of Forward Declaration in Nested Friends

Thinking in c++ volume 1 says :

Making a structure nested doesn’t automatically give it access to private members. To accomplish this, you must follow a particular form: first, declare (without defining) the nested structure, then declare it as a friend, and finally define the structure. The structure definition must be separate from the friend declaration, otherwise it would be seen by the compiler as a non-member.


But cpp annotations says :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

class Surround
    {
        // class SecondWithin;      not required: friend declarations (see
        //                          below) double as forward declarations

        static int s_variable;
        public:
            class FirstWithin
            {
                friend class Surround;
                friend class SecondWithin;
...
...



which one is correct !?
Last edited on
anybody ...
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
struct enclosing
{
    struct nested_three ; // declaration of class enclosing::nested_three

    struct nested_one
    {
        // A nested class is a member and as such has the same access rights as any other member. - IS
        void foo( enclosing& outer ) { ++outer.i ; }
        // note: therefore, enclosing::nested_one::foo is implicitly a friend of enclosing
        // note: a friend declaration is not required

        private:  int j = 22 ;


        // The members of an enclosing class have no special access to members of a nested class;
        // the usual access rules shall be obeyed. - IS
        friend enclosing ; // enclosing declared to be a friend of enclosing::nested_one
        
        

        // A name nominated by a friend declaration shall be accessible
        // in the scope of the class containing the friend declaration. - IS
        
        // friend nested_two ; // *** error: the name nested_two hasn't been seen
        friend class nested_two ; // fine; declares class enclosing::nested_two to be a friend
        // note: here, 'the scope of the class containing the friend declaration' is the scope of the class enclosing
        // note: therefore, this declares enclosing::nested_two to be a friend class


        friend nested_three ; // fine; there was a declaration of class enclosing::nested_three

    };

    void bar( nested_one& n1 ) { ++n1.j ; } // ok, enclosing is a friend of enclosing::nested_one

    struct nested_two
    {
        // A nested class is a member and as such has the same access rights as any other member. - IS
        void baz2( enclosing& outer ) { ++outer.i ; }

        void foobar2( nested_one& n1 ) { ++n1.j ; } // ok, enclosing::nested_two is a friend of enclosing::nested_one
    };

    struct nested_three
    {
        // A nested class is a member and as such has the same access rights as any other member. - IS
        void baz3( enclosing& outer ) { ++outer.i ; }

        void foobar3( nested_one& n1 ) { ++n1.j ; } // ok, enclosing::nested_three is a friend of enclosing::nested_one
    };

    private:  int i = 8 ;
};


EDIT: To clear any ambiguity: What 'Thinking in c++' said was correct at the time the book was written. In legacy C++, members of a nested class had unrestricted access to only these in the enclosing class: types, static members and enumerators.
Last edited on
thanks !


But how should i approach the below problem:

I want a Egg object to access the private members of the Nest Class...
I did the following :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Header file Hen.h

#pragma once
class Hen{
public:
	class Nest {
		class Egg;
		friend class Egg;
		void access2();
	public:
		class Egg {
			friend class Nest;
		};
	};
};


1
2
3
4
5
6
7
8
9
//Hen.cpp

#include "Hen.h"
#include<iostream>

void Hen::Nest::access2(){

	std::cout << "accessing private nest";
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Source.cpp

#include <iostream>
#include <conio.h>
#include "Hen.h"

void main(){

	Hen::Nest::Egg egg1;
	Hen::Nest nest1;
	egg1.access2();      ////error /////

	_getch();

}





Link :

http://cpp.sh/57dc
Last edited on
> I want a Egg object to access the private members of the Nest Class...

As Hen::Nest::Egg is a member of Hen::Nest, it has access to members of Hen::Nest

To access a non-static member, an object is required.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

class Hen {

    public:
        class Nest {

        private: void private_member() const { std::cout << "Hen::Nest::access_private_member()\n" ; }

        public:
            class Egg {

                public: void access_nest( const Nest& n ) { n.private_member() ; };
            };
        };
};

int main()
{
    Hen::Nest nest ;
    Hen::Nest::Egg egg ;
    egg.access_nest(nest) ;
}

http://coliru.stacked-crooked.com/a/72f59a4b710517ad
http://rextester.com/PXILB12441
Last edited on
 
egg1.access2();      ////error ///// 

The Egg class does not have a member function named access2() so that will not work.
Topic archived. No new replies allowed.