Topic: Curious nested class visibility
Author: gi2nospam@mariani.ws (Gianni Mariani)
Date: Fri, 2 Dec 2005 06:04:56 GMT Raw View
Somone (Mr Dyl) recently posted the predecessor to the code example
below on comp.lang.c++.
What makes me curious is why does the standard not allow Nested_B
visibility into A ? It seems strange that I can find the address of a
member of A but I can't reference a member directly.
class A {
public:
class Nested_A {
protected:
A* ptrA;
};
protected:
int X;
};
class B : public A {
public:
class Nested_B : public Nested_A {
int foo() {return(ptrA->X);}
// error: "A::X" is not accessible through a "A*"
int foo1() {return(ptrA->*(&B::X));} // &B::X == &A::X
};
};
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: squell@alumina.nl (Marc Schoolderman)
Date: Sat, 3 Dec 2005 01:34:25 GMT Raw View
Gianni Mariani wrote:
> What makes me curious is why does the standard not allow Nested_B
> visibility into A ? It seems strange that I can find the address of a
> member of A but I can't reference a member directly.
> class B : public A {
> public:
> class Nested_B : public Nested_A {
> int foo() {return(ptrA->X);}
> // error: "A::X" is not accessible through a "A*"
> int foo1() {return(ptrA->*(&B::X));} // &B::X == &A::X
> };
> };
This is because a nested class does not (in C++98) automatically gain
access to the surrounding class's non-public members unless explicitly
declared a friend:
class foo {
int x;
struct inner {
inner(foo* p) { p->x = 4; } // cannot access foo::x
};
};
GCC doesn't reject foo1(), but it is wrong (afaik). In any case, this
has been recognised as a defect, so it will probably go away in a future
standard, see
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#45
~Marc.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "vish" <vishakha@gmail.com>
Date: Fri, 2 Dec 2005 19:34:00 CST Raw View
Nested_B will have ptrA as protected member. ptrA is an object of class
A and X is a protected member of A, an object cannot access protected
member directly.
-Vish
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: johnchx2@yahoo.com
Date: Sat, 3 Dec 2005 16:16:15 CST Raw View
Gianni Mariani wrote:
> What makes me curious is why does the standard not allow Nested_B
> visibility into A ? It seems strange that I can find the address of a
> member of A but I can't reference a member directly.
This is a manifestion of an open issue, which basically boils down to
"the expression '&Derived::mem' may not have the type you think it
has." If mem has type T and is inherited from Base, &Derived::mem has
the type pointer-to-member-of-Base-of-type-T. (5.3.1/2)
http://www2.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#203
I don't think anyone has previously pointed out that this issue
constitutes an access control loophole.
Let me give a simpler example of the same effect:
class A {
protected:
int i;
};
class B: public A {
public:
void bar( A& a )
{
int A::* pma = &B::i;
int A::* pma2 = &A::i; // error: access violation
int B::* pmb = &B::i;
a.*pma = 5;
a.*pma2 = 5;
a.*pmb = 5; // error: incompatible type
}
};
The first error (access control violation) is what we'd expect: we
can't refer to protected members of A, only to protected members of A
sub-objects of B. The second error (incompatible type) shows that we
can't apply a pointer-to-member-of-B to an object of type A. So far,
so good.
However, the initialization of pma shows that we can create an object
of type pointer-to-member-of-A by naming a member of B. Since access
control applies only to the use of names, this creates a loophole: we
can access a member of one class by naming a member of another.
Personally, I think this raises the importance of issue 203.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]