Why friendship not applicable to function arguments

N

Ninan

When compiling using gcc 2.95.3, I get the following error for the
code snippet posted below.
bash-2.03$ g++ membAccess.C
membAccess.C: In function `int main()':
membAccess.C:13: `struct A B::m_a' is private
membAccess.C:38: within this context
Is this how it is supposed to work or is this a compiler specific issue

1 #include <iostream>
2
3
4 struct A
5 {
6 int y;
7 };
8
9 void useAalter (A* pA);
10 class B
11 {
12
13 A m_a;
14 public:
15 B (A& a)
16 {
17 m_a = a;
18 }
19 A* getA () { return &m_a;}
20 friend void useAalter(A*pA);
21 };
22
23 void useA (A* pA)
24 {
25 std::cout << pA->y << std::endl;
26 }
27
28 void useAalter (A* pA)
29 {
30 std::cout << pA->y << std::endl;
31 }
32
33 int main ()
34 {
35 A a = {45};
36 B bInst (a);
37 useA (bInst.getA());
38 useAalter (&(bInst.m_a)) ;
39 }
 
H

Howard

Ninan said:
When compiling using gcc 2.95.3, I get the following error for the
code snippet posted below.
bash-2.03$ g++ membAccess.C
membAccess.C: In function `int main()':
membAccess.C:13: `struct A B::m_a' is private
membAccess.C:38: within this context
Is this how it is supposed to work or is this a compiler specific issue

1 #include <iostream>
2
3
4 struct A
5 {
6 int y;
7 };
8
9 void useAalter (A* pA);
10 class B
11 {
12
13 A m_a;
14 public:
15 B (A& a)
16 {
17 m_a = a;
18 }
19 A* getA () { return &m_a;}
20 friend void useAalter(A*pA);

This makes the function useAalter a friend. So far, so good.
21 };
22
23 void useA (A* pA)
24 {
25 std::cout << pA->y << std::endl;
26 }
27
28 void useAalter (A* pA)
29 {
30 std::cout << pA->y << std::endl;
31 }
32
33 int main ()
34 {
35 A a = {45};
36 B bInst (a);
37 useA (bInst.getA());
38 useAalter (&(bInst.m_a)) ;

But here, you're getting an error because you're trying to resolve
&(bInst.m_a), and pass that as an A*. But you're in main() here, not in
useAalter() yet. The value you're trying to pass has to be resolved _here_,
then passed as an A* parameter to useAalter(). And it can't be resolved
here, because main() is not a friend of the class A.

If you want to access the private member of bInst, you could make the
parameter to useAalter() some kind of reference or pointer to a B instance,
instead of a pointer to an A instance. Then you'd pass bInst (or its
address) to useAalter(), instead of the address of bInst.m_a.

-Howard
 
K

Kaz Kylheku

Ninan said:
When compiling using gcc 2.95.3, I get the following error for the
code snippet posted below.
bash-2.03$ g++ membAccess.C
membAccess.C: In function `int main()':
membAccess.C:13: `struct A B::m_a' is private
membAccess.C:38: within this context
Is this how it is supposed to work or is this a compiler specific issue

1 #include <iostream>
2
3
4 struct A
5 {
6 int y;
7 };
8
9 void useAalter (A* pA);
10 class B
11 {
12
13 A m_a;
14 public:
15 B (A& a)
16 {
17 m_a = a;
18 }
19 A* getA () { return &m_a;}
20 friend void useAalter(A*pA);
21 };

Because useAalter is a friend of class B, it is allowed to access
private members in that class.

28 void useAalter (A* pA)
29 {
30 std::cout << pA->y << std::endl;
31 }

But useAalter does not actually access anything in class B. This
function makes no use of its frienship to B whatsoever. It accesses the
identifier A::y. This is allowed because y is public in struct A.
32
33 int main ()
34 {
35 A a = {45};
36 B bInst (a);
37 useA (bInst.getA());
38 useAalter (&(bInst.m_a)) ;
39 }

Here, it is the function main which accesse the name B::m_a in line 38.
Since main isn't a friend of the class B and m_a is private, this
doesn't work.

Access protection is concerned with name lookups, not pointer
dereferences.

The function useAalter has no idea that the A * which it is working
with is in fact B::m_a. It could be any A struct whatsoever:

A a = { 45 };

useAalter(&a); // nothing to do with any B object
 
Y

Yong Hu

Howard said:
This makes the function useAalter a friend. So far, so good.


But here, you're getting an error because you're trying to resolve
&(bInst.m_a), and pass that as an A*. But you're in main() here, not in
useAalter() yet. The value you're trying to pass has to be resolved _here_,
then passed as an A* parameter to useAalter(). And it can't be resolved
here, because main() is not a friend of the class A.

The error message "`struct A B::m_a' is private" is saying that main is
not a friend of class B and thus class B's private member could not be
accessed in main.
 
H

Howard

Yong Hu said:
The error message "`struct A B::m_a' is private" is saying that main is
not a friend of class B and thus class B's private member could not be
accessed in main.

Yeah, that's what I meant. I accidently said "not a friend of class _A_",
when I mean "_B_".

-Howard
 

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
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top