class A {
protected:
int f()
{return 0;};
};
class B : public A {
public:
int g(){
A a;
return a.f();
};
};
Not bad? Visual C++ 6.0 says:
error C2248: 'f' : cannot access protected member declared in class 'A'
On the other hand, following code compiles:
class A {
protected:
int f() {return 0;};
};
class B : public A {
public:
int g(){
return f();
};
};
Is this correct, I mean compliant with the standard? It seems like they
try to distinguish the access for "this" from "foreign", but I don't
think this "feature" is present in C++. C++, at least what I know about
it, only uses the type to determine the access.
Or, am I wrong?
Ales
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
: How about this one:
[snip]
: Is this correct, I mean compliant with the standard?
Yes.
: It seems like they
: try to distinguish the access for "this" from "foreign", but I don't
: think this "feature" is present in C++. C++, at least what I know about
: it, only uses the type to determine the access.
Mostly correct. It distinguishes this type from foreign type not
object.
: Or, am I wrong?
Well slightly. This seems to be the most thoroughly misunderstand
concept in C++ :-)
class A { protected: int i; };
class B : public A { };
class D;
class C : public A { void f(A&, B&, C&, D&); };
class D : public C { };
void C::f (A& a, B& b, C& c, D& d) {
A ca;
i = 5; // ok, the A part of me
ca.i = 5; // error, not the A part of a C
a.i = 5; // error, not the A part of a C
b.i = 5; // error, not the A part of a C
c.i = 5; // ok, the A part of another C
d.i = 5; // ok, the A part of the C part of a D
}
John
Yes, yes :-).
Your first example tries to access via
A::f()
which fails because this is not declared public.
The second example uses
B::f()
which works because it's inherited protected.
Thiemo Seufer
> How about this one:
>
> class A {
> protected:
> int f()
> {return 0;};
> };
>
> class B : public A {
> public:
> int g(){
> A a;
> return a.f();
> };
> };
>
> Not bad? Visual C++ 6.0 says:
> error C2248: 'f' : cannot access protected member declared in class 'A'
The error is valid. Section 11.5.1 [class.protected] of the standard
states:
"When a friend or a member function of a derived class references
a protected nonstatic member of a base class, an access check
applies ... the access must be through a pointer to, reference to,
or object of the derived class itself (or any class derived from
that class)"
Since class B is trying to access f through an A object, not a B (or a
derived-from-B) object, the access violates the above statement.
--
kevin kostrzewa
work: kkost...@csisolutions.com
home: tkk...@newsguy.com
Yes. A "protected" function in class A can be called by directly by a
subclass B object, but the call to "a.f()" is the same situation as
calling "a.f()" from an unrelated class C. I.e., not allowed.
> It seems like
> they try to distinguish the access for "this" from "foreign", but I
> don't think this "feature" is present in C++. C++, at least what I
> know about it, only uses the type to determine the access.
The access afforded by "protected" is very specific, namely that
a subclass of A is allowed to call f on objects of that subclass
(this normally includes objects of subclasses of the subclass).
I don't have the standard itself (think it's too vague to be worth
even $1), but I do have the second committe draft, CD2, and I'd be
surprised if the final standard is very different. So here's
ze relevant quote:
----------------------------------------------------------------
[class.protected] 11.5 Protected member access
1 When a friend or a member function of a derived class references a
protected nonstatic member of a base class, an access check applies in
addition to those described earlier in this clause.100) Except when
forming a pointer to member (5.3.1), the access must be through a
pointer to, reference to, or object of the derived class itself (or any
class derived from that class) (5.2.5). If the access is to form a
pointer to member, the nestednamespecifier shall name the derived
class (or any class derived from that class). [Example:
class B {
protected:
int i;
static int j;
};
class D1 : public B {
};
class D2 : public B {
friend void fr(B*,D1*,D2*);
void mem(B*,D1*);
};
void fr(B* pb, D1* p1, D2* p2)
{
pb>i = 1; // illformed
p1>i = 2; // illformed
p2>i = 3; // ok (access through a D2)
p2>B::i = 4; // ok (access through a D2, qualification ignored)
int B::* pmi_B = &B::i; // illformed
int B::* pmi_B2 = &D2::i; // ok (type of &D2::i is "int B::*")
B::j = 5; // ok (because refers to static member)
D2::j =6; // ok (because refers to static member)
}
void D2::mem(B* pb, D1* p1)
{
pb>i = 1; // illformed
p1>i = 2; // illformed
i = 3; // ok (access through ?this?)
B::i = 4; // ok (access through ?this?, qualification ignored)
j = 5; // ok (because refers to static member)
B::j = 6; // ok (because refers to static member)
}
void g(B* pb, D1* p1, D2* p2)
{
pb>i = 1; // illformed
p1>i = 2; // illformed
p2>i = 3; // illformed
}
-end example]
__________________ 100) This additional check does not apply to other
members, e.g. static data members or enumerator member constants.
----------------------------------------------------------------
Hth.,
- Alf
--
alf_DOT_steinbach_AT_ac_DOT_com (clean the address before replying)
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
>How about this one:
>
>class A {
>protected:
> int f()
> {return 0;};
>};
>
>class B : public A {
>public:
> int g(){
> A a;
> return a.f();
> };
>};
>
>Not bad? Visual C++ 6.0 says:
>error C2248: 'f' : cannot access protected member declared in class 'A'
>
>On the other hand, following code compiles:
>
>class A {
>protected:
> int f() {return 0;};
>};
>
>class B : public A {
>public:
> int g(){
> return f();
> };
>};
>
>Is this correct, I mean compliant with the standard? It seems like they
>try to distinguish the access for "this" from "foreign", but I don't
>think this "feature" is present in C++. C++, at least what I know about
>it, only uses the type to determine the access.
>
>Or, am I wrong?
The compiler is correct.
A derived class has access to protected members of a base class
only when referenced through a derived class object. It has no
special rights to access protected members of arbitrary base
class objects.
>From the standard (11.5)
When a friend or a member function of a derived class
references a protected nonstatic member of a base class,
an access check applies in addition to those described
earlier in clause 11. Except when forming a pointer to
member (5.3.1), the access must be through a pointer to,
reference to, or object of the derived class itself (or
any class derived from that class) (5.2.5). If the access
is to form a pointer to member, the nested要ame貞pecifier
shall name the derived class (or any class derived from
that class).
--
Michael M Rubenstein