friends and nested classes

P

Paul

In the code below I have the operator << work OK for classes A and B
but cannot make it work for class C. The error I am getting currently
points to this line:

friend std::eek:stream& operator <<(std::eek:stream&, const B::C&);

saying class C (in const B::C&) is inaccessible, although, as I see
it, this has been added to class B:

friend std::eek:stream& operator <<(std::eek:stream&, const C&);

Is there a way to make it work?

Thank you.

#include <ostream>

class A {
class B {
class C {
friend std::eek:stream& operator <<(std::eek:stream&, const C&);
};

friend std::eek:stream& operator <<(std::eek:stream&, const B&);
friend std::eek:stream& operator <<(std::eek:stream&, const C&);
};

friend std::eek:stream& operator <<(std::eek:stream&, const A&);
friend std::eek:stream& operator <<(std::eek:stream&, const B&);
friend std::eek:stream& operator <<(std::eek:stream&, const B::C&);
};

inline std::eek:stream& operator <<(std::eek:stream& os, const
A&) { return os; }
inline std::eek:stream& operator <<(std::eek:stream& os, const
A::B&) { return os; }
inline std::eek:stream& operator <<(std::eek:stream& os, const
A::B::C&) { return os; }
 
Ö

Öö Tiib

In the code below I have the operator << work OK for classes A and B
but cannot make it work for class C. The error I am getting currently
points to this line:

    friend std::eek:stream& operator <<(std::eek:stream&, const B::C&);

saying class C (in const B::C&) is inaccessible, although, as I see
it, this has been added to class B:

        friend std::eek:stream& operator <<(std::eek:stream&, const C&);

Is there a way to make it work?

Thank you.

#include <ostream>

class A {
    class B {
        class C {
            friend std::eek:stream& operator <<(std::eek:stream&, const C&);
        };

        friend std::eek:stream& operator <<(std::eek:stream&, const B&);
        friend std::eek:stream& operator <<(std::eek:stream&, const C&);
    };

    friend std::eek:stream& operator <<(std::eek:stream&, const A&);
    friend std::eek:stream& operator <<(std::eek:stream&, const B&);
    friend std::eek:stream& operator <<(std::eek:stream&, const B::C&);

};

inline std::eek:stream& operator <<(std::eek:stream& os, const
A&)                    { return os; }
inline std::eek:stream& operator <<(std::eek:stream& os, const
A::B&)                 { return os; }
inline std::eek:stream& operator <<(std::eek:stream& os, const
A::B::C&)              { return os; }

This is about implicit private. Usually the very same people who use
it are also the ones who are most confused by it. Always specify
access explicitly, then you hopefully see yourself what you write.
 
P

Paul

This is about implicit private. Usually the very same people who use
it are also the ones who are most confused by it. Always specify
access explicitly, then you hopefully see yourself what you write.- Hide quoted text -

I do appreciate that I did not explicitly use the word 'private' to
denote a private section in a class:

class A {
private:
// data member/functions
};

and do apologise if you found this confusing. The real class has more
members than in the example provided and contains both public and
private sections exlicitly introduced by public/private keywords. None
the less, with the keyword 'private' inserted, the sections in the
classes in the above example are private by design - and I was trying
to work it out how to use 'friend' declarations to make required
sections accessible to the 'operator <<' operators.
 
B

Bo Persson

Paul said:
I do appreciate that I did not explicitly use the word 'private' to
denote a private section in a class:

class A {
private:
// data member/functions
};

and do apologise if you found this confusing. The real class has
more
members than in the example provided and contains both public and
private sections exlicitly introduced by public/private keywords.
None
the less, with the keyword 'private' inserted, the sections in the
classes in the above example are private by design - and I was
trying
to work it out how to use 'friend' declarations to make required
sections accessible to the 'operator <<' operators.

And in that case, A (and things declared in A) cannot access B::C
because C is private to B.


Bo Persson
 
Ö

Öö Tiib

I do appreciate that I did not explicitly use the word 'private' to
denote a private section in a class:

class A {
private:
    // data member/functions

};

and do apologise if you found this confusing. The real class has more
members than in the example provided and contains both public and
private sections exlicitly introduced by public/private keywords. None
the less, with the keyword 'private' inserted, the sections in the
classes in the above example are private by design - and I was trying
to work it out how to use 'friend' declarations to make required
sections accessible to the 'operator <<' operators.

Yes but does not error message tell to you that A::B::C is private for
B and so not accessible for A?

The friend declaration does declare but does not introduce names into
enclosing namespace. Therefore friend declarations in A::B::C or in
A::B do not declare the friend function for A.

The class A::B::C must be accessible for A to declare a function using
it in A. Other option is that the function is declared in enclosing
namespace first and then any class may claim friendship with it (but
not A, because functions using A::B::C can not be declared before A is
defined).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,039
Messages
2,570,376
Members
47,029
Latest member
EmiliaSton

Latest Threads

Top