How come I am able to access my private function

N

Nivvy

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
 
V

vindhya

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.
 
J

John Carson

Nivvy said:
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;
}
 
S

Sharad Kala

Nivvy said:
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
 
S

Sharad Kala

Zorro said:
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
 
Z

Zorro

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.
 
S

Sharad Kala

vindhya said:
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
 
Z

Zorro

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.
 
M

Matthias Kaeppler

Sharad said:
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.
 
E

Earl Purple

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.
 
B

benben

... 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
 
M

Matthias Kaeppler

benben said:
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.
 
M

Matthias Kaeppler

Earl said:
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>
 
J

Jonathan Mcdougall

Matthias said:
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
 
D

David Rasmussen

Matthias said:
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
 
J

John Carson

Matthias Kaeppler said:
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.
 
Z

Zorro

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
(e-mail address removed)
http://www.zhmicro.com
http://distributed-software.blogspot.com
 
B

Ben Pope

Zorro said:
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
 
Z

Zorro

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.com/2005/07/in-context-of-c-absurdity-is-synonym.html

Regards,
Z.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top