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 

virtual functions & permissions
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Jon Heiner
Guest





PostPosted: Tue Oct 07, 2003 1:45 am    Post subject: virtual functions & permissions Reply with quote



I looked through several resources and was unable to turn
up a definitive answer on this question ( note, i don't have
a copy of the standard handy. )

What's the deal with virtual functions and permissions? The
following compiles ( on VC7 which is by no means the gold
standard ) but I am unsure both why it doesn't complain, and
why it works. The function seems to be called successfully,
but imho violates permissions. Although the permission of a
function is not part of it's type, so I can see how it resolves.

Would like a technical, standards-based answer on this please.
Thx, Jon

----------------------------------------------------------------

class Base
{
public:
virtual void PublicMember( void );
private:
virtual void PrivateMember( void );
};

class Derived : public Base // here comes the slight of hand
{
public:
virtual void PrivateMember( void );
private:
virtual void PublicMember( void );
};

void foo( void )
{
Derived d;
Base * pB = &d;
d->PublicMember(); // now this calls a private member of Derived, or not?
}

// lastly, what happens if ( ad nauseum ):

class MoreDerived : public Derived
{
public:
virtual void PublicMember( void );
};


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Joshua Lehrer
Guest





PostPosted: Tue Oct 07, 2003 6:14 pm    Post subject: Re: virtual functions & permissions Reply with quote



"Jon Heiner" <jheinerNOSPAM (AT) pandemicstudiosNOSPAM (DOT) com> wrote


Quote:
void foo( void )
{
Derived d;
Base * pB = &d;
d->PublicMember(); // now this calls a private member of Derived, or not?
}


Clearly, you meant "pB->PublicMember()"?

Whether or not you can call a method is determined based on the static
type of the object. This is determined at compile time.

Which method ultimately gets called is determined based on the dynamic
type of the object. This is determined at run time.

Example:

pBase->func();

The compiler checkes whether the consumer has permission to call
Base::func(). If the consumer does, assuming func() is now determined
to be virtual, code is inserted to dispatch a call to the method
func(). It has to be this way. The *compiler* doesn't always know
what the dynamic type of the underlying object is. All it knows is
that it has a base pointer.

At runtime, when this code is reached, the appropriate "func()" is
called based on what the real underlying type of the pointer is,
because this can be determined at runtime via dispatch tables.

pSub = new Sub;
pBase = pSub;


Here is an example:

"func.h"
class base {
public
virtual void method() = 0;
};
void func(base * pBase);


"func.cpp"
void func(base * pBase) {
pBase->method();
}


"foo.cpp"
class foo : public base {
private:
virtual void method()
};

When compiling func.cpp, all the compiler knows is that it has a
base*. It has no way of knowing that this base* is really a foo*, or
a bar*, or something else. It determines that it is allowed to call
"method" on "pBase" because the static type of "pBase" is base*, and
"method" is public on base.

It isn't until runtime that it is determined that the ultimate method
to be called is foo::method, and by that time, there is no such thing
as public/protected/private.

There are many patterns that are based on the fact that virtual
functions protection levels are based on the static type held by the
consumer.

I recommend you read up on the "templated method pattern" for an
example.

joshua lehrer
factset research systems
NYSE:FDS

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Richard Smith
Guest





PostPosted: Tue Oct 07, 2003 6:18 pm    Post subject: Re: virtual functions & permissions Reply with quote



Jon Heiner wrote:

Quote:
class Base
{
public:
virtual void PublicMember( void );
private:
virtual void PrivateMember( void );
};

class Derived : public Base // here comes the slight of hand
{
public:
virtual void PrivateMember( void );

This is perfectly legal: there is nothing to stop you from
overriding a private virtual function.

Quote:
private:
virtual void PublicMember( void );
};

void foo( void )
{
Derived d;
Base * pB = &d;
d->PublicMember(); // now this calls a private member of Derived, or not?

Errr... this won't compile. You either mean

pB->PublicMember();

in which case the access control is done on the static type
of the object (ie. Base), and the call is perfectly legal;
or you mean

d.PublicMember();

in which case access control again happens on the static
type (this time Derived), and the call is illegal.

Quote:
class MoreDerived : public Derived
{
public:
virtual void PublicMember( void );
};

Again this is legal. Whether a function overrides another
function in the base class is entirely independent of either
functions access specifier.

--
Richard Smith

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Siemel Naran
Guest





PostPosted: Tue Oct 07, 2003 6:23 pm    Post subject: Re: virtual functions & permissions Reply with quote

"Jon Heiner" <jheinerNOSPAM (AT) pandemicstudiosNOSPAM (DOT) com> wrote in message

Quote:
class Base
{
public:
virtual void PublicMember( void );
private:
virtual void PrivateMember( void );
};

class Derived : public Base // here comes the slight of hand
{
public:
virtual void PrivateMember( void );
private:
virtual void PublicMember( void );
};

void foo( void )
{
Derived d;
Base * pB = &d;
d->PublicMember(); // now this calls a private member of Derived, or
not?
}

Yes, you're calling a private member. It would be nice if C++ enforced that
the function in the inherited class has the same access level as the
function in the base class. At least you can enforce the rule through
coding standards.

--
+++++++++++
Siemel Naran


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Yuval Hofshy
Guest





PostPosted: Tue Oct 07, 2003 6:26 pm    Post subject: Re: virtual functions & permissions Reply with quote

Hi,

I guess you meant:

void foo( void )
{
Derived d;
Base * pB = &d;
pB->PublicMember();
}


It's ok. There is no permissions violation here, because permissions
are tested according to the type used to perform the call (e.g. Base).
Here is what the standard says:


11.6 Access to virtual functions
================================
The access rules (clause 11) for a virtual function are determined by
its declaration and are not affected by the rules for a function that
later overrides it.
[Example:

class B {
public:
virtual int f();
};
class D : public B {
private:
int f();
};
void f()
{
D d;
B* pb = &d;
D* pd = &d;

pb->f(); //OK: B::f() is public,
//D::f() is invoked
pd->f(); //error: D::f() is private
}

—end example]
Access is checked at the call point using the type of the expression
used to denote the object for which the member function is called (B*
in the example above). The access of the member function in the class
in which it was defined (D in the example above) is in general not
known.



Hope that helps,
Yuval

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Thomas Richter
Guest





PostPosted: Tue Oct 07, 2003 6:34 pm    Post subject: Re: virtual functions & permissions Reply with quote

Hi,

Quote:
What's the deal with virtual functions and permissions? The
following compiles ( on VC7 which is by no means the gold
standard ) but I am unsure both why it doesn't complain, and
why it works. The function seems to be called successfully,
but imho violates permissions. Although the permission of a
function is not part of it's type, so I can see how it resolves.

VC7 is a lot better than VC6, and that's from a g++ believer. (-;

Quote:
class Base
{
public:
virtual void PublicMember( void );
private:
virtual void PrivateMember( void );
};

class Derived : public Base // here comes the slight of hand
{
public:
virtual void PrivateMember( void );
private:
virtual void PublicMember( void );
};

void foo( void )
{
Derived d;
Base * pB = &d;
d->PublicMember(); // now this calls a private member of Derived, or not?

This won't compile as it is. Did you mean

d.PublicMember(); /* won't compile since Derived::PublicMember is private */

or

pB->PublicMember(); /* will compile since Base::PublicMember is public */

The latter will of course call Derived::PublicMember() since it overloads
Base::PublicMember().

Thus, you've here a construction were a method can only be savely called
thru the base class. This might make sense in some situations where, for
example, you want to enforce that a separate module of your application
should *not* deal with derived classes directly since you want to hide
the information in them thru an interface defined by the base class.

To answer your question, "permission checks" are done at compile time,
unlike virtual function calls, which are resolved at run-time.

Quote:
// lastly, what happens if ( ad nauseum ):

class MoreDerived : public Derived
{
public:
virtual void PublicMember( void );
};

If that is the only modification you do in your program, nothing changes
since you never hold any object of type "MoreDerived". If, on the other
hand, you initialize "d" to be of type "MoreDerived", then pb->PublicMember()
will call MoreDerived::PublicMember() and the program will compile since
Base::PublicMember() is public.

So long,
Thomas


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Antoun Kanawati
Guest





PostPosted: Tue Oct 07, 2003 6:39 pm    Post subject: Re: virtual functions & permissions Reply with quote

In the derived classes, you can "expose" the privates of the
parent.

However, you should not be able to hide the parent's publics
in the derived class, especially since you're using
public inheritance.

In your particular case, you are calling through a Base
pointer, where PublicMember is still public; so, there is
no problem. Now, since the function is virtual and the
call is virtual too, the most derived implementation will
be called.

So far, this is all as expected (given that the code has
compiled).

So, the real question is: should the code have compiled
in the first place?

Jon Heiner wrote:
Quote:
....
----------------------------------------------------------------

class Base
{
public:
virtual void PublicMember( void );
private:
virtual void PrivateMember( void );
};

class Derived : public Base // here comes the slight of hand
{
public:
virtual void PrivateMember( void );
private:
virtual void PublicMember( void );
};

void foo( void )
{
Derived d;
Base * pB = &d;
d->PublicMember(); // now this calls a private member of Derived, or not?
}

// lastly, what happens if ( ad nauseum ):

class MoreDerived : public Derived
{
public:
virtual void PublicMember( void );
};

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ron Natalie
Guest





PostPosted: Tue Oct 07, 2003 6:40 pm    Post subject: Re: virtual functions & permissions Reply with quote


"Jon Heiner" <jheinerNOSPAM (AT) pandemicstudiosNOSPAM (DOT) com> wrote


Quote:

What's the deal with virtual functions and permissions? The
following compiles

The following descirbes the way member functions are called:

1. The name is looked up.
2. Possible overloads for that name are considered.
3. Access is checked.
4. Virtual function substitution occurs.


Quote:
Derived d;
Base * pB = &d;
d->PublicMember(); // now this calls a private member of Derived, or not?
}

Yes...Perhaps what you really wanted to write here is:

pB->PublicMember();

In this case the name is looked up as Base::PublicMember. The only overload
is PublicMember(void), so that is selected. Access is checked (public, which is
fine here). Then Derived::PublicMember is subsituted.

It makes no difference what Derived::PublicMember's access is in this case. The
access is checked based on the static test. It has to be done at compile time (since
access errors make a program ill-formed).



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
WW
Guest





PostPosted: Tue Oct 07, 2003 7:07 pm    Post subject: Re: virtual functions & permissions Reply with quote

Jon Heiner wrote:
Quote:
I looked through several resources and was unable to turn
up a definitive answer on this question ( note, i don't have
a copy of the standard handy. )

What's the deal with virtual functions and permissions? The
following compiles ( on VC7 which is by no means the gold
standard ) but I am unsure both why it doesn't complain, and
why it works. The function seems to be called successfully,
but imho violates permissions. Although the permission of a
function is not part of it's type, so I can see how it resolves.

Would like a technical, standards-based answer on this please.
Thx, Jon

----------------------------------------------------------------

class Base
{
public:
virtual void PublicMember( void );
private:
virtual void PrivateMember( void );
};

class Derived : public Base // here comes the slight of hand
{
public:
virtual void PrivateMember( void );
private:
virtual void PublicMember( void );
};

AFAIk this is all OK... from the language rules point of view. Some
compilers will give warnings, but that is all and even that is not required.
It is silly, but it works. Visibility is not checked in overriding:

struct Somebase {
void templateMethod() {
if (priv1()) {
priv2();
} else {
priv3();
}
}
private:
virtual void priv1() = 0;
virtual void priv2() = 0;
virtual void priv3() = 0;
};

struct Concrete : Somebase {
// ...
private:
virtual void priv1() {...}
virtual void priv2() {...}
virtual void priv3() {...}
};

--
WW aka Attila



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ron
Guest





PostPosted: Tue Oct 07, 2003 7:11 pm    Post subject: Re: virtual functions & permissions Reply with quote

Quote:
I looked through several resources and was unable to turn
up a definitive answer on this question ( note, i don't have
a copy of the standard handy. )

What's the deal with virtual functions and permissions? The
following compiles ( on VC7 which is by no means the gold
standard ) but I am unsure both why it doesn't complain, and
why it works. The function seems to be called successfully,
but imho violates permissions. Although the permission of a
function is not part of it's type, so I can see how it resolves.

Would like a technical, standards-based answer on this please.
Thx, Jon

----------------------------------------------------------------

class Base
{
public:
virtual void PublicMember( void );
private:
virtual void PrivateMember( void );
};

class Derived : public Base // here comes the slight of hand
{
public:
virtual void PrivateMember( void );
private:
virtual void PublicMember( void );
};

void foo( void )
{
Derived d;
Base * pB = &d;
d->PublicMember(); // now this calls a private member of Derived, or not?
}

This can't compile. Did you mean "d.PublicMember();"? But that should
fail to compile as well, because D's override of PublicMember () is
private, and you're calling it through an object of static type D. Did
you mean "pB->PublicMember ()"? That should compile, because,
according to s.11.6(1), "The access rules (clause 11) for a virtual
function are determined by its declaration and are not affected by the
rules for a function that later overrides it."

-Ron

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jon Heiner
Guest





PostPosted: Tue Oct 07, 2003 7:13 pm    Post subject: Re: virtual functions & permissions Reply with quote

thx for the replies. the answer was sitting almost word for word
in clause 11.6 of the standard. now, to follow up, didn't meyers
or sutter have some comments on doing this? i looked through
meyers I & II before posting the original question to no avail.
anyone? bueller? anyone? ...


"Jon Heiner" <jheinerNOSPAM (AT) pandemicstudiosNOSPAM (DOT) com> wrote

Quote:
I looked through several resources and was unable to turn
up a definitive answer on this question ( note, i don't have
a copy of the standard handy. )

What's the deal with virtual functions and permissions? The
following compiles ( on VC7 which is by no means the gold
standard ) but I am unsure both why it doesn't complain, and
why it works. The function seems to be called successfully,
but imho violates permissions. Although the permission of a
function is not part of it's type, so I can see how it resolves.

Would like a technical, standards-based answer on this please.
Thx, Jon

----------------------------------------------------------------

class Base
{
public:
virtual void PublicMember( void );
private:
virtual void PrivateMember( void );
};

class Derived : public Base // here comes the slight of hand
{
public:
virtual void PrivateMember( void );
private:
virtual void PublicMember( void );
};

void foo( void )
{
Derived d;
Base * pB = &d;
d->PublicMember(); // now this calls a private member of Derived, or not?
}

// lastly, what happens if ( ad nauseum ):

class MoreDerived : public Derived
{
public:
virtual void PublicMember( void );
};


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Gerhard Menzl
Guest





PostPosted: Wed Oct 08, 2003 6:28 pm    Post subject: Re: virtual functions & permissions Reply with quote

Jon Heiner wrote:

Quote:
thx for the replies. the answer was sitting almost word for word
in clause 11.6 of the standard. now, to follow up, didn't meyers
or sutter have some comments on doing this? i looked through
meyers I & II before posting the original question to no avail.
anyone? bueller? anyone? ...

Search Google Groups for "Private Interface" for lengthy discussions on
the subject.

Short summary:

class Interface
{
public:
virtual void f () = 0;
};

class Implementation : private Interface
{
// public interface

private:
virtual void f ();
};

is a perfectly logical and sane thing to do (unless you are a strictly
orthodox Kanzian who would never write an abstract base class that does
not check pre- and postconditions).

Gerhard Menzl


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Gerhard Menzl
Guest





PostPosted: Wed Oct 08, 2003 6:29 pm    Post subject: Re: virtual functions & permissions Reply with quote

Siemel Naran wrote:

Quote:
It would be nice if C++ enforced that the function in the inherited
class has the same access level as the function in the base class.
At least you can enforce the rule through coding standards.

I beg to differ. The value of separating access level and virtual
dispatch has been shown and discussed repeatedly. Search Google Groups
for "Private Interface".

People wanting the language to make design decisions for them may be
better off using Java or C#.

Gerhard Menzl


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Thu Oct 09, 2003 8:19 pm    Post subject: Re: virtual functions & permissions Reply with quote

Gerhard Menzl <gerhard.menzl (AT) kapsch (DOT) net> wrote

Quote:
Jon Heiner wrote:

thx for the replies. the answer was sitting almost word for word in
clause 11.6 of the standard. now, to follow up, didn't meyers or
sutter have some comments on doing this? i looked through meyers I
& II before posting the original question to no avail. anyone?
bueller? anyone? ...

Search Google Groups for "Private Interface" for lengthy discussions
on the subject.

Short summary:

class Interface
{
public:
virtual void f () = 0;
};

class Implementation : private Interface
{
// public interface

private:
virtual void f ();
};

is a perfectly logical and sane thing to do

What is the purpose of it? Most coding guidelines I've seen say not to
be more restrictive in the derived class, since it doesn't help; the
client code can always call the function via a pointer or a reference to
the base class.

Quote:
(unless you are a strictly orthodox Kanzian who would never write an
abstract base class that does not check pre- and postconditions).

The idiom for verifying pre- and postconditions depends on the public
functions of the interface not being virtual. The virtual functions are
normally private, so the derived class isn't likely to be more
restrictive. (Depending on the situation, it might be appropriate for
the derived class to be less restrictive, and make its implementation
public or proctected. The case has never occured in my code, however.)

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Siemel Naran
Guest





PostPosted: Fri Oct 10, 2003 4:19 pm    Post subject: Re: virtual functions & permissions Reply with quote

<kanze (AT) gabi-soft (DOT) fr> wrote in message

Quote:
The idiom for verifying pre- and postconditions depends on the public
functions of the interface not being virtual. The virtual functions are
normally private, so the derived class isn't likely to be more
restrictive. (Depending on the situation, it might be appropriate for
the derived class to be less restrictive, and make its implementation
public or proctected. The case has never occured in my code, however.)

I find the virtual functions are normally protected so that the derived
class version can call the base class version.

--
+++++++++++
Siemel Naran


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
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.