By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,902 Members | 4,597 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,902 IT Pros & Developers. It's quick & easy.

How come I am able to access my private function

P: n/a
HI all,

I just wondered by seeing the o/p of the program. Let me know wt is the
reason.

class Base
{
public :
virtual void f1()
{
cout << "Base::f1() "<<endl;
}
};

class Derived : public Base
{
private:
void f1()
{
cout << "Derived::f1() "<<endl;
}
};

int main()
{
Base *bp = new Derived;
bp->f1();

return 0;
}
It ouputs the Derived private function.
What is the reason, whether this is like breaking OOPS.

-Nivvy

Jul 23 '05 #1
Share this Question
Share on Google+
22 Replies


P: n/a
No, you are not breaking OOPS. The writers of the compiler are
incompetent. You should get an error when changing anything in
redefining a virtual function, including its access.

Regards,
Dr. Z.
Chief Scientist
zo****@ZHMicro.com
http://www.zhmicro.com
http://distributed-software.blogspot.com

Jul 23 '05 #2

P: n/a
Thats what virtual function is all about buddy. You have declared it as
virtual and compiler has assigned a VPTR for your function f1(). Now
when you try to access f1 of type derived via base class pointer you
will land up in derived class since VPTR points to derived f1.
To verify just declare another private function in derived say f2 and
try to access. It will not.
Remember only virtual function in base class and implemented in derived
are accesible in this manner.

Jul 23 '05 #3

P: n/a

"Nivvy" <ve*******@gmail.com> wrote in message
HI all,

I just wondered by seeing the o/p of the program. Let me know wt is the
reason.

class Base
{
public :
virtual void f1()
{
cout << "Base::f1() "<<endl;
}
};

class Derived : public Base
{
private:
void f1()
{
cout << "Derived::f1() "<<endl;
}
};

int main()
{
Base *bp = new Derived;
bp->f1();


The static (compile time) type of bp is Base*. f1 is defined public in Base,
so it can access it. At run time the type of bp is Derived* and hence the
derived class function is invoked. Access specifiers come into picture only
at compile time.

Sharad
Jul 23 '05 #4

P: n/a

"Zorro" <zo****@comcast.net> wrote in message
No, you are not breaking OOPS. The writers of the compiler are
incompetent. You should get an error when changing anything in
redefining a virtual function, including its access.


Can you quote the Standard about the aforementioned statement ?

Sharad
Jul 23 '05 #5

P: n/a

"vindhya" <ma*********@gmail.com> wrote in message
Thats what virtual function is all about buddy. You have declared it as
virtual and compiler has assigned a VPTR for your function f1(). Now


There is nothing like VPTR in standard C++. That's implementation specific.

Others: I will like to know what other ways can one implement virtual
functions. I know this is offtopic but am just curious.

Sharad
Jul 23 '05 #6

P: n/a
"Nivvy" <ve*******@gmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com
HI all,

I just wondered by seeing the o/p of the program. Let me know wt is
the reason.

class Base
{
public :
virtual void f1()
{
cout << "Base::f1() "<<endl;
}
};

class Derived : public Base
{
private:
void f1()
{
cout << "Derived::f1() "<<endl;
}
};

int main()
{
Base *bp = new Derived;
bp->f1();

return 0;
}
It ouputs the Derived private function.
What is the reason, whether this is like breaking OOPS.


This is in accordance with section 11.6 of the standard. When a function is
accessed using a base pointer, access rights are determined by the
declaration in the base class. At least one reason for this is that the
object being pointed to is not in general known at compile time; it is
resolved at runtime. Note that if you access the Derived class function
using a pointer to the Derived class, then its private access status is
respected, e.g.,

int main()
{
Base *bp = new Derived;
Derived *dp = new Derived;
bp->f1(); // compiles
dp->f1(); // won't compile

return 0;
}
--
John Carson

Jul 23 '05 #7

P: n/a
OK. So, you are saying because the implementation of VPTR is in a
certain way, the compiler could not have seen that you are changing the
access of a virtual method? Are we speaking of parsing, or the
implementation of V-tables?

Regards,
Z.

Jul 23 '05 #8

P: n/a
Yes, it is section 11.6.

I forgot I have deviated quite a bit from the standard in correcting
such anomalies. Since the compiler can in fact see that just as it can
see the throw and other method specifications, this is an anomaly. One
should not be able to access a private part. But for C++, that is the
standard.

Sorry about that, and thanks.

Regards.

Jul 23 '05 #9

P: n/a
Sharad Kala wrote:
The static (compile time) type of bp is Base*. f1 is defined public in Base,
so it can access it. At run time the type of bp is Derived* and hence the
derived class function is invoked. Access specifiers come into picture only
at compile time.


.... which is a definitive flaw in the design of C++. It almost
encourages you to break your own code.

--
Matthias Kaeppler
Jul 23 '05 #10

P: n/a
private: is an *access* specifier, not a guard. It does not prevent
the function being called, just being accessed directly.

The function is being accessed indirectly, through the base class where
it is permitted.

The same is true if you have a function that returns by reference a
member variable which is declared as private. private only prevents
direct access.

Jul 23 '05 #11

P: n/a
> ... which is a definitive flaw in the design of C++. It almost
encourages you to break your own code.


C++ is a tool nontheless. Making a public base virtual member function
private is asking for trouble and ill treating. Do you blame a screwdriver
not drilling a good hole for you?

Regards,
Ben
Jul 23 '05 #12

P: n/a
benben wrote:
C++ is a tool nontheless. Making a public base virtual member function
private is asking for trouble and ill treating. Do you blame a screwdriver
not drilling a good hole for you?


That's a weak argument. What can go wrong, will go wrong. The language
should do whatever it can to NOT let things go wrong.

Java does that by the way.

--
Matthias Kaeppler
Jul 23 '05 #13

P: n/a
Earl Purple wrote:
private: is an *access* specifier, not a guard. It does not prevent
the function being called, just being accessed directly.


So what? The point is, in C++, access modifiers are not part of the
function signature, as in Java for example. If that was the case,
compiling that program would _fail_.
Java doesn't suffer from this weakness.

<snip>

--
Matthias Kaeppler
Jul 23 '05 #14

P: n/a
Matthias Kaeppler wrote:
Earl Purple wrote:
private: is an *access* specifier, not a guard. It does not prevent
the function being called, just being accessed directly.


So what? The point is, in C++, access modifiers are not part of the
function signature, as in Java for example.
If that was the case,
compiling that program would _fail_.
Java doesn't suffer from this weakness.


C++ allows derived classes to change the protection of members. That
was a design decisions. Java apparently decided the contrary. I see no
"weakness" here.
Jonathan

Jul 23 '05 #15

P: n/a
Matthias Kaeppler wrote:

That's a weak argument. What can go wrong, will go wrong. The language
should do whatever it can to NOT let things go wrong.

Java does that by the way.


Does what it can do make sure things do not go wrong? No, I am afraid
Java doesn't do that. It would be nice, though.

/David
Jul 23 '05 #16

P: n/a
"Matthias Kaeppler" <no****@digitalraid.com> wrote in message
news:db*************@news.t-online.com
benben wrote:
C++ is a tool nontheless. Making a public base virtual member
function private is asking for trouble and ill treating. Do you
blame a screwdriver not drilling a good hole for you?


That's a weak argument. What can go wrong, will go wrong. The language
should do whatever it can to NOT let things go wrong.

Java does that by the way.


Speaking of weak arguments...The only way to stop things going wrong is to
stop programmers from writing programs. That is true of Java, as it is true
of every other programming language. The question is whether, in each case,
offering programmers extra flexibility and/or extra speed is worth the
possibly increased risk of error. Contrary to your claim, Java does not do
"whatever it can" to stop errors. Doing that would mean you couldn't write
programs in Java.

What is the benefit of the current rule? Well, one thing you can do with it
is the following. Suppose you have a succession of derivations A <- B <- C
<- D ... where B derives from A, C derives from B and so on. Suppose that A
is an abstract class with a public pure virtual function of foo(). Suppose
further than foo() is private in all of the other classes. The effect of
this is to prevent the more derived classes from calling the function in the
less derived classes (e.g., you stop C calling B::foo() ). In some contexts,
this could be sensible design.

In the case of a single level derivation, some people make derived classes
entirely private with the view that the class should only be accessed via a
pointer/reference to an abstract base class.

--
John Carson

Jul 23 '05 #17

P: n/a
> The same is true if you have a function that returns by reference a
member variable which is declared as private. private only prevents
direct access.


Elsewhere in this post it was stated that these are design decisions.
So, I will not argue with what BS had accomplished via C++ front at the
time and it was accepted as is by the committee. Nevertheless, that is
the standard now, and like the screw-driver example in this post, one
must know the language well, and be very careful.

However, the argument that the language should not provide
opportunities for mistakes is correct. Private implies that only the
class itself (or friends) can access the item. Listing exceptions to
the rule in a standard is not very helpful.

This post brings out another un-noticed design issue. The author
mentions the one loophole that can potentially make "private" specifier
useless. Note that, programs can be fixed by less experienced
engineers, or as I have seen many times, by someone who finds he can
fix it in 5 minutes instead of changing the design over a few days. The
fix becomes an obscure defect for others because it is counter to
normal way of thinking in terms of OO design.

In fixing C++ loopholes, I had to block two things:

1. You cannot return reference to a non-public member.
2. You cannot return a pointer to a non-public member.

Regards,
Dr. Z.
Chief Scientist
zo****@ZHMicro.com
http://www.zhmicro.com
http://distributed-software.blogspot.com

Jul 23 '05 #18

P: n/a
Zorro wrote:
Yes, it is section 11.6.

I forgot I have deviated quite a bit from the standard in correcting
such anomalies. Since the compiler can in fact see that just as it can
see the throw and other method specifications, this is an anomaly. One
should not be able to access a private part. But for C++, that is the
standard.


The basic premise of inheritance is that when you access a derived class through a base pointer it behaves as if it is an instance of a base, can be treated like a base, and for
all intents an purposes IS an instance of the base class.

And so, you think that derived classes should be able to change the interface of the base class? That just doesn't make sense. If you want to change the interface of the base
class, by all means inherit from it (publicly or privately), but if it no longer behaves as a base class, don't treat it as one.

I see no weakness, except in the use of the language and in the understanding of inheritance, by the programmer.

Ben
--
I'm not just a number. To many, I'm known as a String...
Jul 23 '05 #19

P: n/a
I just added a new item to my blogger regarding this matter. This is a
good reasoning. Here is my brief view (the blogger has more). I could
be wrong.

The pointer to base is to relax the strong type checking so
polymorphism can be used. It is quite true that the compiler will not
know about more members and methods added to the derive class. However,
the virtual functions are intended to provide different definitions in
derived classes, so one includes them in the base. I would make a
private method private at the base (so I never encountered this
problem). But what about a typing error?

The new blogger is about a few things that came up in this newsgroup.

http://distributed-software.blogspot...s-synonym.html

Regards,
Z.

Jul 23 '05 #20

P: n/a
Nivvy schreef:
HI all,

I just wondered by seeing the o/p of the program. Let me know wt is the
reason.

class Base
{
public :
virtual void f1()
{
cout << "Base::f1() "<<endl;
}
};

class Derived : public Base
{
private:
void f1()
{
cout << "Derived::f1() "<<endl;
}
};

int main()
{
Base *bp = new Derived;
bp->f1();

return 0;
}
It ouputs the Derived private function.
What is the reason, whether this is like breaking OOPS.


The reason for this is that Derived implements not only its own
interface, but also the Base interface. In the Base interface,
f1 is public. That means anybody who use the Base interface can
get f1 - independent of the class implementing that interface.

In your case, Derived implements the Base interface for f1 and
main uses that interface. Both sides follow proper OO rules, so
the compiler doesn't stop you.

Now, the Derived interface doesn't offer f1. That may seem strange
but there is no OO requirement for that. A derived class may offer
additional interfaces which are not supersets of the Base interface.
(This is also what allows Multiple Inheritance - those interfaces
are also incompatible with Base ).

HTH,
Michiel Salters

Jul 23 '05 #21

P: n/a
Nivvy wrote:
It ouputs the Derived private function.
What is the reason, whether this is like breaking OOPS.

There's nothing broken. Access control is checked before the virtual
function overriding happens. You can generally view a member function
call as working this way:

1. The name is looked up. (In this case *bp is type Base, so Base::f1
is found).

2. Overloads for that name are checked. There is only one f1(void).

3. Then access control is checked. Base::f1(void) is public.

4. Then since Base::f1 is virtual, the dynamic type is checked for
overriding functions and Derived::f1 is executed.
Jul 23 '05 #22

P: n/a
David Rasmussen wrote:
Does what it can do make sure things do not go wrong? No, I am afraid
Java doesn't do that. It would be nice, though.


You misunderstand me. I didn't mean Java makes sure that everything
works. it by far doesn't. With "Java does that" I was referring to Java
suppressing exactly the problem we're talking about, by checking the
function signature at compile time. So in this point, Java /does/ make
sure this thing can't go wrong (and that's perfectly fine!).
It's also not a performance penalty, since this check is done at compile
time.

--
Matthias Kaeppler
Jul 23 '05 #23

This discussion thread is closed

Replies have been disabled for this discussion.