473,322 Members | 1,314 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

Private virt function can be called with Base class ptr

Hello
I wanted to understand a contradictory design of C++

class A
{public:
virtual void f(){ cout<<" base f"<<endl; }
};

class B:public A
{
private:
void f(){ cout<<"private derived B f"<<endl;};
};
main()
{
B b;
A* p = &b;
p->f();
}

why does the compiler allows me to call a private function in B though
accessing it directly is not possible;(B b; b.f() gives error)
Vijay
Jul 19 '05 #1
6 3135
On Fri, 22 Aug 2003 11:49:27 +0530, "vijay" <ge********@yahoo.com> wrote:
Hello
I wanted to understand a contradictory design of C++

class A
{public:
virtual void f(){ cout<<" base f"<<endl; }
};

class B:public A
{
private:
void f(){ cout<<"private derived B f"<<endl;};
};
main()
Just a note: the standard requires 'main' to have return type 'int'.

{
B b;
A* p = &b;
p->f();
}

why does the compiler allows me to call a private function in B though
accessing it directly is not possible;(B b; b.f() gives error)


That's no big mystery. The compiler uses the statically available type,
namely A. It cannot check at compile time the dynamic type of *p (well,
it can in this particular case, but not in general).

More difficult: why does C++ allow you to change a method from 'public'
to 'private' in a derived class?

Well, it can be useful in some cases. Determining in which cases it's
more confusing than useful would be hard, if not practically impossible.
And so C++ allows it, because 'the programmer knows best'; some other
languages disallow it, because 'the compiler knows best'.

Jul 19 '05 #2
vijay wrote:
Hello
I wanted to understand a contradictory design of C++

class A
{public:
virtual void f(){ cout<<" base f"<<endl; }
};

class B:public A
{
private:
void f(){ cout<<"private derived B f"<<endl;};
};
main()
{
B b;
A* p = &b;
p->f();
}

why does the compiler allows me to call a private function in B though
accessing it directly is not possible;(B b; b.f() gives error)


Actually - I should say - it is your design, which is flawed, not C++. The
function f() is part of your public interface. C++ allows you to put it
private in the derived class (it even allows you to put it private in a base
class and then later override it and bring it public) and make it public in
the base, but that usually makes absolutely no sense to do so. In most
cases classes in a hierarchy must conform to the Liskov Substitution
Principle ( http://tinyurl.com/ktb5 [
http://www.eventhelix.com/RealtimeMa...v_substitution
_principle.htm ] )
which in turn requires all derived classes to be substitutable in place of
the base. Shortly: whereever you can use a type A object, you must be able
to use a type B object as well. Now this - in turn - means that you publish
your interface in class A, and you will not change it or its meaning in any
subsequent derivations.

The wuestion (why does C++ allow it) is valid, but IMHO not so disturbing.
As Alf described it very well, C++ takes the route of not limiting the
programmers actions rather than trying to figure out what is good or wrong.
Now I do not recall any use for this scenario you have just shown to us -
but it may very well be my memory, it does not mean that there is no use for
this.

C++ has been designed at the beginning of OO. What I mean is that at that
time OO was not in widespread use, C++ was new as well etc. so the designers
of the language decided that unless they can prove that some combination of
features is absolutely useless or definitely harmful, they will allow it. I
guess this is one example of this thinking here.

Have you asked about the same "trick" the other way around, I could have
talked about the idiomatic C++ implementation of the Template Method (
http://c2.com/cgi/wiki?TemplateMethodPattern )pattern. In the template
method implementation in C++ the virtual hooks for the non-virtual template
methods are defined as private in the base class. This is done so, because
they must not be used directly, only indirectly using the template method.
In the subclasses it is not possible to call them, but it is possible to
override them - this overriding is also done as private functions. So while
in that pattern we do not change between public/private, a similarly
astonishing trick is used: we cannot call base class private virtual
function, but we can "rewrite" them in a subclass. (Of course if those
hooks might be useful in a subclass they will be declared as protected, but
then there is no trick. :-) )
--
Attila aka WW
Jul 19 '05 #3
Hi
The simple principle followed by C++ in accessing virtual functions is
as follows...
1. Availability .
Whether the function u are calling is available... In this case it is
available in the class A
2. Accessibility :
Whether the function u are calling is accessible .. It is accessible
in Class A which is public
3. Virtiual :
Whether the function is virtual . . It is in this case... The compiler
will built a vtable and store the address of function of the derived class
function.
As far as the access check is concerned it is done at compile time only ..
So it passes through and u can bypass the private access of the derived
class. The pointer u are using is still the base class pointer.
If u try the reverse way i mean u make base class function private and
derived class function public the compilation wont go through because the
compiler will fail in the second step..

So this is the reason why it is possible.

Param
Siemens Information Systems Ltd
"Attila Feher" <at**********@lmf.ericsson.se> wrote in message
news:bi**********@newstree.wise.edt.ericsson.se...
vijay wrote:
Hello
I wanted to understand a contradictory design of C++

class A
{public:
virtual void f(){ cout<<" base f"<<endl; }
};

class B:public A
{
private:
void f(){ cout<<"private derived B f"<<endl;};
};
main()
{
B b;
A* p = &b;
p->f();
}

why does the compiler allows me to call a private function in B though
accessing it directly is not possible;(B b; b.f() gives error)
Actually - I should say - it is your design, which is flawed, not C++.

The function f() is part of your public interface. C++ allows you to put it
private in the derived class (it even allows you to put it private in a base class and then later override it and bring it public) and make it public in the base, but that usually makes absolutely no sense to do so. In most
cases classes in a hierarchy must conform to the Liskov Substitution
Principle ( http://tinyurl.com/ktb5 [
http://www.eventhelix.com/RealtimeMa...v_substitution _principle.htm ] )
which in turn requires all derived classes to be substitutable in place of
the base. Shortly: whereever you can use a type A object, you must be able to use a type B object as well. Now this - in turn - means that you publish your interface in class A, and you will not change it or its meaning in any subsequent derivations.

The wuestion (why does C++ allow it) is valid, but IMHO not so disturbing.
As Alf described it very well, C++ takes the route of not limiting the
programmers actions rather than trying to figure out what is good or wrong. Now I do not recall any use for this scenario you have just shown to us -
but it may very well be my memory, it does not mean that there is no use for this.

C++ has been designed at the beginning of OO. What I mean is that at that
time OO was not in widespread use, C++ was new as well etc. so the designers of the language decided that unless they can prove that some combination of features is absolutely useless or definitely harmful, they will allow it. I guess this is one example of this thinking here.

Have you asked about the same "trick" the other way around, I could have
talked about the idiomatic C++ implementation of the Template Method (
http://c2.com/cgi/wiki?TemplateMethodPattern )pattern. In the template
method implementation in C++ the virtual hooks for the non-virtual template methods are defined as private in the base class. This is done so, because they must not be used directly, only indirectly using the template method.
In the subclasses it is not possible to call them, but it is possible to
override them - this overriding is also done as private functions. So while in that pattern we do not change between public/private, a similarly
astonishing trick is used: we cannot call base class private virtual
function, but we can "rewrite" them in a subclass. (Of course if those
hooks might be useful in a subclass they will be declared as protected, but then there is no trick. :-) )
--
Attila aka WW

Jul 19 '05 #4
Param wrote:
Hi
The simple principle followed by C++ in accessing virtual
functions is as follows...

[SNIP]

a.) Why do you post this as a reply to me?

b.) Why do you top-post?
http://www.parashift.com/c++-faq-lit...t.html#faq-5.4

BTW the OP did not ask for what - mechanism make this work in this way -
but - why is this nonsense allowed (if you let me exaggerate). At least
that was my understanding.

--
Attila aka WW


Jul 19 '05 #5
Thanks param,But I know this,
u can look at my question that why does c++ design allowed this !!!!
vijay

"Param" <se******@yahoo.com> wrote in message
news:bi**********@news.mch.sbs.de...
Hi
The simple principle followed by C++ in accessing virtual functions is
as follows...
1. Availability .
Whether the function u are calling is available... In this case it is available in the class A
2. Accessibility :
Whether the function u are calling is accessible .. It is accessible in Class A which is public
3. Virtiual :
Whether the function is virtual . . It is in this case... The compiler will built a vtable and store the address of function of the derived class
function.
As far as the access check is concerned it is done at compile time only ..
So it passes through and u can bypass the private access of the derived
class. The pointer u are using is still the base class pointer.
If u try the reverse way i mean u make base class function private and
derived class function public the compilation wont go through because the
compiler will fail in the second step..

So this is the reason why it is possible.

Param
Siemens Information Systems Ltd
"Attila Feher" <at**********@lmf.ericsson.se> wrote in message
news:bi**********@newstree.wise.edt.ericsson.se...
vijay wrote:
Hello
I wanted to understand a contradictory design of C++

class A
{public:
virtual void f(){ cout<<" base f"<<endl; }
};

class B:public A
{
private:
void f(){ cout<<"private derived B f"<<endl;};
};
main()
{
B b;
A* p = &b;
p->f();
}

why does the compiler allows me to call a private function in B though
accessing it directly is not possible;(B b; b.f() gives error)
Actually - I should say - it is your design, which is flawed, not C++.

The
function f() is part of your public interface. C++ allows you to put it
private in the derived class (it even allows you to put it private in a

base
class and then later override it and bring it public) and make it public

in
the base, but that usually makes absolutely no sense to do so. In most
cases classes in a hierarchy must conform to the Liskov Substitution
Principle ( http://tinyurl.com/ktb5 [

http://www.eventhelix.com/RealtimeMa...v_substitution
_principle.htm ] )
which in turn requires all derived classes to be substitutable in place of the base. Shortly: whereever you can use a type A object, you must be

able
to use a type B object as well. Now this - in turn - means that you

publish
your interface in class A, and you will not change it or its meaning in

any
subsequent derivations.

The wuestion (why does C++ allow it) is valid, but IMHO not so disturbing. As Alf described it very well, C++ takes the route of not limiting the
programmers actions rather than trying to figure out what is good or

wrong.
Now I do not recall any use for this scenario you have just shown to us - but it may very well be my memory, it does not mean that there is no use

for
this.

C++ has been designed at the beginning of OO. What I mean is that at that time OO was not in widespread use, C++ was new as well etc. so the

designers
of the language decided that unless they can prove that some combination

of
features is absolutely useless or definitely harmful, they will allow it. I
guess this is one example of this thinking here.

Have you asked about the same "trick" the other way around, I could have
talked about the idiomatic C++ implementation of the Template Method (
http://c2.com/cgi/wiki?TemplateMethodPattern )pattern. In the template
method implementation in C++ the virtual hooks for the non-virtual

template
methods are defined as private in the base class. This is done so,

because
they must not be used directly, only indirectly using the template

method. In the subclasses it is not possible to call them, but it is possible to
override them - this overriding is also done as private functions. So

while
in that pattern we do not change between public/private, a similarly
astonishing trick is used: we cannot call base class private virtual
function, but we can "rewrite" them in a subclass. (Of course if those
hooks might be useful in a subclass they will be declared as protected,

but
then there is no trick. :-) )
--
Attila aka WW


Jul 19 '05 #6
"vijay" <ge********@yahoo.com> wrote in message news:<bi**********@news.mch.sbs.de>...
class A
{public:
virtual void f(){ cout<<" base f"<<endl; }
};

class B:public A
{
private:
void f(){ cout<<"private derived B f"<<endl;};
};
main()
{
B b;
A* p = &b;
p->f();
}

why does the compiler allows me to call a private function in B though
accessing it directly is not possible;(B b; b.f() gives error)


All the compiler is allowed to consider when compiling p->f() is that
p is a pointer to A and A::f is public. Access specifiers are a
compile-time feature and are not checked when dispatching virtual
function calls at run-time.

More importantly: Never attempt to hide a function inherited from a
public base class. Users can always access any public function in a
public base class through a pointer or reference to that class, even
if it refers to a derived class where that function is hidden. If you
can't support the entirety of the base class interface, don't inherit
it -- at least, not publicly:

class Base {
public: void f ();
void g ();
};

// private inheritance and using declarations
class PrivateInheritance : private Base {
public: using Base::f; // make Base::f accessible
};

// composition and proxy methods
class Composition {
public: void f () { myBase.f(); } // make Base::f accessible
private: Base myBase;
};

See also this thread:

<http://groups.google.com/groups?th=9aacc58aeaa1bc4>

- Shane
Jul 19 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Phui Hock | last post by:
"When you make a virtual function call through a base-class pointer (that is, when you make a polymorphic call), the compiler quietly inserts code to fetch the VPTR and look up the function address...
8
by: Andreas Lagemann | last post by:
Hi, after browsing FAQ and archive for a while I decided that the following is a legal question. Consider this: Class Base { public: Base() {}
20
by: modemer | last post by:
Question is as in subject. For example: class BaseClass { public: void func() { do something; } // I don't want this function being overloaded in its inherited class };
10
by: Abelardo Vacca | last post by:
Hi, The title sums up the question pretty much. I would like to access all private members of a class including the private members of its base classes.( I already have the ReflectionPermission )...
4
by: voidtwerp | last post by:
The following code cant call derived::fn() , it is calling base::fn() which is pure virtual. (the same problem is ocurring if I do it outside of constructors also) What am I doing wrong here? ...
6
by: noel.hunt | last post by:
I have a base class, PadRcv, with virtual functions. User code will derive from this class and possibly supply it's own functions to override the base class virtual functions. How can I test that...
4
by: Javier | last post by:
Hello, is this possible? I have a pure virtual function in the base class (to force the programmers of the derived classes to have this function implemented) but I want to call the derived class...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.