Protected member friend

M

MiG

Hello,

Consider the following code snippet:

class B
{
protected:
B() {}
~B() {}
};

class A
{
friend B:B();

public:
A() {}
~A() {}
};

Compiling this code produces the following error:
error C2248: 'B::B' : cannot access protected member declared in class 'B'

Why can I not give B's constructor privileged access to A?
 
B

Barry

MiG said:
Hello,

Consider the following code snippet:

class B
{
protected:
B() {}
~B() {}
};

class A
{
friend B:B();

typo : => ::
public:
A() {}
~A() {}
};

Compiling this code produces the following error:

you got the error wrong
It means you can't access B::B within A(when you're granting friend),
because B::B is protected
Why can I not give B's constructor privileged access to A?

There are two ways to solve this

way 1:
class A;

class B
{
friend class A;
protected:
B() {}
~B() {}
};

class A
{
friend B::B();
public:
A() {}
~A() {}
};

//////////////////////////

way 2:

class B
{
public:
B() {}
~B() {}
};

class A
{
friend B::B();
public:
A() {}
~A() {}
};
 
V

Victor Bazarov

Barry said:
typo : => ::


you got the error wrong
It means you can't access B::B within A(when you're granting friend),
because B::B is protected


There are two ways to solve this

The first "way" is an unnecessarily complicated version of the
second "way", which means there is only one way - just grant the
friendship of 'A' to 'B::B()' and that's all.
way 1:
class A;

No need.
class B
{
friend class A;

No need either. Test it. When friendship is granted, access
is not required. If 'A' grants friendship to a function of 'B',
it does not have to have access to that function of 'B'.
protected:
B() {}
~B() {}
};

class A
{
friend B::B();
public:
A() {}
~A() {}
};

//////////////////////////

way 2:

class B
{
public:
B() {}
~B() {}
};

class A
{
friend B::B();
public:
A() {}
~A() {}
};

V
 
B

Barry

Victor said:
The first "way" is an unnecessarily complicated version of the
second "way", which means there is only one way - just grant the
friendship of 'A' to 'B::B()' and that's all.


No need.


No need either. Test it. When friendship is granted, access
is not required. If 'A' grants friendship to a function of 'B',
it does not have to have access to that function of 'B'.
Well, my compiler(msvc8.0) hates the program again

I try msvc6.0 and icl 9.1 both work
 
F

Frank Birbacher

Hi!
way 2:

class B
{
public:
B() {}
~B() {}
};

class A
{
friend B::B();
public:
A() {}
~A() {}
};

In this case you wouldn't need "friend" at all, would you?

Frank
 
V

Victor Bazarov

Frank said:
Hi!


In this case you wouldn't need "friend" at all, would you?

Of course not. To make it closer to the test condition, do:

class B
{
public:
B();
~B();
};

class A
{
int i;
friend B::B();
public:
A() {}
~A() {}
};

B::B() {
A a;
a.i = 42;
}

B::~B() {
A a;
a.i = 42; // shouldn't compile
}

V
 
V

Victor Bazarov

Frank said:
I tried msvc8 express on this:

class B
{
friend class A;
^^^^^^^^^^^^^^^
Drop this, it's unnecessary.
protected:
B() {}
~B() {}
};

class A
{
friend B::B();
public:
A() {}
~A() {}
};

which compiles cleanly.

Try actually exercising the friendship next time. See my other
post for a program that does that.

V
 
F

Frank Birbacher

Hi!
Well, my compiler(msvc8.0) hates the program again

I tried msvc8 express on this:

class B
{
friend class A;
protected:
B() {}
~B() {}
};

class A
{
friend B::B();
public:
A() {}
~A() {}
};

which compiles cleanly.

Frank
 
M

MiG

Victor said:
The first "way" is an unnecessarily complicated version of the
second "way", which means there is only one way - just grant the
friendship of 'A' to 'B::B()' and that's all.

I need to force specialization of a non-abstract class and thought that
the way to do this would be by protecting the constructors.

Is there any other way of doing this without protecting the constructors
and not making the class abstract?

Thanks Victor (and everybody) for your replies.
 
B

Barry

Victor said:
^^^^^^^^^^^^^^^
Drop this, it's unnecessary.

to Frank:

if this is drop msvc8.0 fails to compile, maybe you should view right
from the OP to see what was going on. :)

///////////////////////////

Thanks V

I think this is a big bug in msvc8.0
 
F

Frank Birbacher

Hi!

Victor said:
Try actually exercising the friendship next time. See my other
post for a program that does that.

I'm sorry. I missed your point in my last post. Now I got it. I used the
following program:

class B
{
protected:
B() {}
~B() {}
};

class A
{
friend B::B();
public:
A() {}
~A() {}
};

And I happen not to have any compiler which accepts it. I tried:
MinGW 3.4.2
MSVC 8 Express
linuc gcc 4.1.2

So, even gcc 4.1.2 rejects it o_O

But I tried the EDG front end on the Dinkumware website. And tried
Comeau (same front end, isn't it?). Both accept it. And on the
Dinkumware site I ran MSVC 6 which also accepts the code. So Microsoft
didn't improve on this issue.

Frank
 
M

MiG

MiG said:
I need to force specialization of a non-abstract class and thought that
the way to do this would be by protecting the constructors.

Is there any other way of doing this without protecting the constructors
and not making the class abstract?

Thanks Victor (and everybody) for your replies.


Lack of sleep has its consequences, I guess.

Made a crucial mistake in my post. I meant my question to be:

Is there any other way of doing this without *de-protecting* the
constructors and not making the class abstract?
 
S

Siddharth Jain

Made a crucial mistake in my post. I meant my question to be:

Is there any other way of doing this without *de-protecting* the
constructors and not making the class abstract?


You can write:

class B
{
public :
B(){}

protected:
~B(){}
};

class A
{
friend B::B();

public:
A(){}
~A(){}
};

normal users won't be able to create an object of class B and B::B()
has access to all class A members.
 

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,989
Messages
2,570,207
Members
46,782
Latest member
ThomasGex

Latest Threads

Top