Re: Access to operator delete of a private nested class
Vyacheslav Lanovets ha scritto:
On May 30, 10:27 pm, Dennis <djmuhlest...@gmail.com> wrote:
I'm not sure exactly according to the spec, which is correct, but gcc
can compile it without error/warning too.
Yes, I installed cygwin to check it in gcc. I've been studiing
Standard for the pas two day trying to figure out what is right and
what is wrong. Also I found how to workaround this by placing "friend
void destory<B>(B*)" into class A declaration.
I think that MS VC is correct: If I declare such class in global scope
and make its dtor and operator delete private then none of the
compilers accepts the code. And my understanding is that access rules
should be the same in this case and in the case of private nested
class.
I believe VC is wrong, while gcc and Comeau are correct.
Even if B is private in A, the members of B are declared public. Outside
the scope of A you can't refer to the name A::B (because it's private)
but once you get hold of an object of type B, then you can call any
member of it that is declared public. Think about it, it can't be
otherwise, if all members of B were private outside the scope of A, you
couldn't even call B's destructor!
Allowing such access would mean that destroy<> can be specialized so
that access to class A::B is given to any code.
Access specifiers are only about names, not types. Outside the scope of
A, you can't legally refer to the *name* A::B, but you *can* manipulate
an object of type A::B if you are given one. Consider this code:
class A
{
private:
class B
{
public:
void f();
};
public:
B get();
};
void foo()
{
A a;
a.get().f(); // legal
}
On the other hand this means that private nested classes are very
limited: it is impossible to use std::tr1::shared_ptr<> inside such a
class without knowledge of shared_ptr<> internals. In case of
Boost.org boost::checked_delete should be marked a friend of class A.
They aren't. And even if they were, you don't need to know much of the
shared_ptr<> internals to provide a custom deleter. Consider this:
class A
{
public:
static shared_ptr<A> factory()
{
return shared_ptr<A>(new A, destroy);
}
private:
A();
~A();
void* operator new(size_t);
void operator delete(void*);
static void destroy(A* ptr)
{
delete ptr;
}
};
A is a class that cannot be instantiated on the stack nor allocated on
the heap with new/delete. The only way to instantiate an object of type
A is through its static method factory() which returns a shared_ptr.
Even if operator delete and the destructor are private, the shared_ptr
is still able to properly dispose of the object, because it is fed with
the custom deleter destroy().
HTH,
Ganesh
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]