C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Private access in an implementation still allows public acce

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Guest






PostPosted: Sun Feb 26, 2006 2:06 am    Post subject: Private access in an implementation still allows public acce Reply with quote



Please consider the following code:

class Abstract
{
public:
virtual ~Abstract() {}
virtual void Method() = 0;
};

class Concrete : public virtual Abstract
{
private:
virtual void Method() {}
};

void UseAbstract()
{
Concrete concrete;
Abstract& abstract = concrete;

abstract.Method();
}


The implementation for Abstract::Method provided in the Concrete class
is private even though the declaration of the method is public in the
derived base class. Yet, compiling the code on three different
compilers produces no errors or warnings. I think many developer might
find this surprising and puzzling. I, myself, am not sure what to
think of it.

The end effect is that the implementation for the Abstract class works
as expected. An instance of Concrete can be used as an Abstract
instance and it works as expected with respect to the Abstract
interface. Method is public for Abstract and can be accessed just
fine, even though it is private with respect to its Concrete
implementation.

However, it seems that there is something wrong, or at least worrisome
about the fact that this can be done.

What can people say about the correctness of this code?
If it is correct, what are the reasons classes are allow to behave this
way?
Back to top
John Carson
Guest





PostPosted: Sun Feb 26, 2006 2:06 am    Post subject: Re: Private access in an implementation still allows public Reply with quote



<tron.thomas (AT) verizon (DOT) net> wrote in message
news:1140916630.241439.309100 (AT) t39g2000cwt (DOT) googlegroups.com
Quote:
Please consider the following code:

class Abstract
{
public:
virtual ~Abstract() {}
virtual void Method() = 0;
};

class Concrete : public virtual Abstract
{
private:
virtual void Method() {}
};

void UseAbstract()
{
Concrete concrete;
Abstract& abstract = concrete;

abstract.Method();
}


The implementation for Abstract::Method provided in the Concrete class
is private even though the declaration of the method is public in the
derived base class. Yet, compiling the code on three different
compilers produces no errors or warnings. I think many developer
might find this surprising and puzzling. I, myself, am not sure what
to think of it.

What object a reference refers to cannot always be known at compile time but
may instead only be known at run time. Access rules are enforced at compile
time, so access rules cannot depend on the object referred to. Instead, they
depend on the type of the reference, since this is known at compile time.
The type of abstract is "reference to Abstract" and Method() is public in
Abstract. Accordingly, access must be allowed.

--
John Carson
Back to top
Guest






PostPosted: Sun Feb 26, 2006 6:06 pm    Post subject: Re: Private access in an implementation still allows public Reply with quote



John Carson wrote:
Quote:

What object a reference refers to cannot always be known at compile time but
may instead only be known at run time. Access rules are enforced at compile
time, so access rules cannot depend on the object referred to. Instead, they
depend on the type of the reference, since this is known at compile time.
The type of abstract is "reference to Abstract" and Method() is public in
Abstract. Accordingly, access must be allowed.

--
John Carson

Thanks John. That makes sense.
Back to top
Neil Cerutti
Guest





PostPosted: Mon Feb 27, 2006 8:06 pm    Post subject: Re: Private access in an implementation still allows public Reply with quote

On 2006-02-26, tron.thomas (AT) verizon (DOT) net <tron.thomas (AT) verizon (DOT) net> wrote:
Quote:
Please consider the following code:

class Abstract
{
public:
virtual ~Abstract() {}
virtual void Method() = 0;
};

class Concrete : public virtual Abstract
{
private:
virtual void Method() {}
};

void UseAbstract()
{
Concrete concrete;
Abstract& abstract = concrete;

abstract.Method();
}


The implementation for Abstract::Method provided in the Concrete class
is private even though the declaration of the method is public in the
derived base class. Yet, compiling the code on three different
compilers produces no errors or warnings. I think many developer might
find this surprising and puzzling. I, myself, am not sure what to
think of it.

It is this way because the alternative seemed worse. The C++ designers
deemed it would be horrible if changing the access specification of a
member function somewhere in your class hierarchy could alter the
resolution of a virtual function call, or cause your program to no
longer compile. Consider multiple inheritance:

class B {
public:
virtual void foo();
};

class X: public B {
private:
void foo();
};

class Y: public B {
public:
void foo();
};

class Fubar: public X, Y {
public:
void foo();
};

In this hierarchy, under a rule that made the private foo in X
inaccessible, there would be no ambiguity in the following call in
function fnagn. It would have to resolve to the public override in B.

void fnagn(Fubar* f)
{
f->foo();
}

But if the access specification of foo in X were then changed to
public, suddenly your code would not even compile.

So the actual rules make your code more robust, in theory. The call to
foo in fnagn is ambiguous, despite foo in X being private.

--
Neil Cerutti
Back to top
Phlip
Guest





PostPosted: Mon Feb 27, 2006 9:06 pm    Post subject: Re: Private access in an implementation still allows public Reply with quote

Neil Cerutti wrote:

Quote:
But if the access specification of foo in X were then changed to
public, suddenly your code would not even compile.

The other odious alternative enforces access at runtime. That would add
extra opcodes to all the virtual functions that don't need them.

The OP should research Design Patterns. Sometimes a method's access is a
valid technique.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Back to top
Phlip
Guest





PostPosted: Mon Feb 27, 2006 9:06 pm    Post subject: Re: Private access in an implementation still allows public Reply with quote

Phlip wrote:

Quote:
Neil Cerutti wrote:

But if the access specification of foo in X were then changed to
public, suddenly your code would not even compile.

The other odious alternative enforces access at runtime. That would add
extra opcodes to all the virtual functions that don't need them.

The OP should research Design Patterns. Sometimes

changing!

Quote:
a method's access is a
valid technique.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Back to top
Neil Cerutti
Guest





PostPosted: Wed Mar 01, 2006 4:06 pm    Post subject: Re: Private access in an implementation still allows public Reply with quote

On 2006-02-27, Neil Cerutti <leadvoice (AT) email (DOT) com> wrote:
Quote:
On 2006-02-26, tron.thomas (AT) verizon (DOT) net <tron.thomas (AT) verizon (DOT) net> wrote:
It is this way because the alternative seemed worse. The C++ designers
deemed it would be horrible if changing the access specification of a
member function somewhere in your class hierarchy could alter the
resolution of a virtual function call, or cause your program to no
longer compile. Consider multiple inheritance:

class B {
public:
virtual void foo();
};

class X: public B {
private:
void foo();
};

class Y: public B {
public:
void foo();
};

class Fubar: public X, Y {
public:
void foo();
};

In this hierarchy, under a rule that made the private foo in X
inaccessible, there would be no ambiguity in the following call in
function fnagn. It would have to resolve to the public override in B.

void fnagn(Fubar* f)
{
f->foo();
}


It seems people got the point, but there were errors in my example code.

Fubar should not declare a function foo, and fnagn should receive
pointer to B.

Quote:
But if the access specification of foo in X were then changed to
public, suddenly your code would not even compile.

So the actual rules make your code more robust, in theory. The call
to foo in fnagn is ambiguous, despite foo in X being private.


--
Neil Cerutti
You can't give him that cutback lane. He's so fast, and he sees
it so well. He can also run away from you if he gets a little
bit of crack. --Dick Lebeau
Back to top
Guest






PostPosted: Wed Mar 01, 2006 8:06 pm    Post subject: Re: Private access in an implementation still allows public Reply with quote

tron.thomas (AT) verizon (DOT) net wrote:
Quote:
Please consider the following code:

class Abstract
{
public:
virtual ~Abstract() {}
virtual void Method() = 0;
};

class Concrete : public virtual Abstract
{
private:
virtual void Method() {}
};

void UseAbstract()
{
Concrete concrete;
Abstract& abstract = concrete;

abstract.Method();
}


The implementation for Abstract::Method provided in the Concrete class
is private even though the declaration of the method is public in the
derived base class. Yet, compiling the code on three different
compilers produces no errors or warnings. I think many developer might
find this surprising and puzzling. I, myself, am not sure what to
think of it.

The end effect is that the implementation for the Abstract class works
as expected. An instance of Concrete can be used as an Abstract
instance and it works as expected with respect to the Abstract
interface. Method is public for Abstract and can be accessed just
fine, even though it is private with respect to its Concrete
implementation.

However, it seems that there is something wrong, or at least worrisome
about the fact that this can be done.

What can people say about the correctness of this code?
If it is correct, what are the reasons classes are allow to behave this
way?

The rule of thumb is that only the names of things can be made private,
not the things themselves. I think the main reason for this is that
it's
not possible at (least currently) to have ironclad protection of
members
that could not be defeated with casts, and have no run-time overhead.

In the particular example you give, I think there are cases where it
could actually be useful. The purpose of private is for the designer
of the class to prevent class users from creating undesired
dependencies
on cretain specifics of the class definition. What the above code is
saying is "don't write any code for Concrete instances using 'method()'
that would not also work for all instances of Abstract".
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.