Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Possible encapsulation violation in C++ (http://www.velocityreviews.com/forums/t289857-possible-encapsulation-violation-in-c.html)

Naresh Agarwal 03-31-2005 11:06 AM

Possible encapsulation violation in C++
 
Hi

Class B
{
public :

virtual void foo()
{
// some impl
}
}

Class D : public B
{
private :

void foo()
{
// some impl
}
}

void main()
{
B *b = new D();
b->foo();
}

This program works fine!

So basically, we are able to access a private function of derived class
using a base class pointer. Why is it allowed in C++? Isn't it
voilation of encapsulation???

thanks & regards,
Naresh Agarwal


Hang Dog 03-31-2005 11:50 AM

Re: Possible encapsulation violation in C++
 


Naresh Agarwal wrote:

> Isn't it
> voilation of encapsulation???
>


No all you have done is fuxored the is-a relationship.


chintoo 03-31-2005 01:21 PM

Re: Possible encapsulation violation in C++
 

Hang Dog wrote:
> Naresh Agarwal wrote:
>
> > Isn't it
> > voilation of encapsulation???
> >

>
> No all you have done is fuxored the is-a relationship.


If it is all about is-a relationship, then why does compiler give error
if we allocate an object of D ( sy d)on stack and say d.foo() . Clearly
its a mix-up.
Effectively the end result points to inconsistent behaviour. If access
specifier was a part of function signature then this problem wouldnt
arise.


lilburne 03-31-2005 01:47 PM

Re: Possible encapsulation violation in C++
 


chintoo wrote:

> Hang Dog wrote:
>
>>Naresh Agarwal wrote:
>>
>>
>>>Isn't it
>>>voilation of encapsulation???
>>>

>>
>>No all you have done is fuxored the is-a relationship.

>
>
> If it is all about is-a relationship, then why does compiler give error
> if we allocate an object of D ( sy d)on stack and say d.foo() . Clearly
> its a mix-up.



Because as a D the method is private but as a B it is public. The B
behaviour is consitent with B, that D behaviour is consitent with it
being a D. The problem is that D is not a B but derived incorrectly.
This is a design issue not a language issue.


> Effectively the end result points to inconsistent behaviour. If access
> specifier was a part of function signature then this problem wouldnt
> arise.
>


There are many ways in which you can get inconsitent behaviour. For
example in one of our old class heirarchies we have a virtual reset()
method. The intent of the method was to reset the instance to the state
it would be in if it were default constructed. A colleague decide this
would be a nice method name for a function which reset an iterator
within a derived class. Result inconsitent behaviour and fuxored is-a
relationship. This is also an example of why virtual methods should not
be public.



Ioannis Vranos 03-31-2005 02:03 PM

Re: Possible encapsulation violation in C++
 
Naresh Agarwal wrote:

> Hi
>
> Class B


class B

> {
> public :
>
> virtual void foo()
> {
> // some impl
>
> }


};

>
> Class D : public B


class

> {
> private :
>
> void foo()
> {
> // some impl
> }


};

>
> void main()


int main()

> {
> B *b = new D();
> b->foo();
> }
>
> This program works fine!
>
> So basically, we are able to access a private function of derived class
> using a base class pointer. Why is it allowed in C++? Isn't it
> voilation of encapsulation???



You can think of it as an intention foo() to be accessible when a D object is treated as a
B object, and not accessible if it is treated as a D object.


To do what you want, you can use private inheritance:



class B
{
public :

virtual void foo()
{
// some impl
}
};

class D : private B
{
private :

void foo()
{
// some impl
}
};

int main()
{
B *b = new D();
b->foo();
}


C:\c\temp.cpp In function `int main()':
23 C:\c\temp.cpp `B' is an inaccessible base of `D'



--
Ioannis Vranos

http://www23.brinkster.com/noicys

ulrich 03-31-2005 03:02 PM

Re: Possible encapsulation violation in C++
 
On 31 Mar 2005 05:21:36 -0800, chintoo <absrivas@gmail.com> wrote:

>
> Hang Dog wrote:
>> Naresh Agarwal wrote:
>>
>> > Isn't it
>> > voilation of encapsulation???
>> >

>>
>> No all you have done is fuxored the is-a relationship.

>
> If it is all about is-a relationship, then why does compiler give error
> if we allocate an object of D ( sy d)on stack and say d.foo() .


because here

D d;
d.foo();

tries to call D::foo(), which is a private member of D and thus not
accessible.

Matthias Kaeppler 03-31-2005 06:32 PM

Re: Possible encapsulation violation in C++
 
lilburne wrote:

>
> Because as a D the method is private but as a B it is public. The B
> behaviour is consitent with B, that D behaviour is consitent with it
> being a D. The problem is that D is not a B but derived incorrectly.
> This is a design issue not a language issue.
>


Actually, it /should/ be a language issue. Access modifiers in Java are
part of the function signature for example. From your standpoint, you
can make everything a design issue.

As to the "D is not a B":

class Bird
{
public:
virtual void fly() = 0;
};

class Blackbird
{
public:
virtual void fly() { // fly in some way }
};

class Penguin
{
private:
virtual void fly() {}
};

A Penguin's wings may be too small to fly. But it's a bird afterall. I
know this is not the cleanest way to express that PenguinS can't fly,
but you get the point.

> There are many ways in which you can get inconsitent behaviour. For
> example in one of our old class heirarchies we have a virtual reset()
> method. The intent of the method was to reset the instance to the state
> it would be in if it were default constructed. A colleague decide this
> would be a nice method name for a function which reset an iterator
> within a derived class. Result inconsitent behaviour and fuxored is-a
> relationship. This is also an example of why virtual methods should not
> be public.
>


Which proves what? One more reason for making it a language issue.


--
Matthias Kaeppler

Matthias Kaeppler 03-31-2005 06:33 PM

Re: Possible encapsulation violation in C++
 
Matthias Kaeppler wrote:

> class Blackbird

: public Bird
> {
> public:
> virtual void fly() { // fly in some way }
> };
>
> class Penguin

: public Bird
> {
> private:
> virtual void fly() {}
> };



Sorry.

--
Matthias Kaeppler

Jerry Coffin 03-31-2005 11:14 PM

Re: Possible encapsulation violation in C++
 
Matthias Kaeppler wrote:

[ ... ]

> As to the "D is not a B":
>
> class Bird
> {
> public:
> virtual void fly() = 0;
> };
>
> class Blackbird
> {
> public:
> virtual void fly() { // fly in some way }
> };
>
> class Penguin
> {
> private:
> virtual void fly() {}
> };
>
> A Penguin's wings may be too small to fly. But it's a bird afterall.


No it's not -- at least by your definition. Inclusion of "fly" as a
member of the base class specifies a class invariant -- specifically
that "all birds can fly." By that definition, a Penguin is NOT a bird.

Ultimately, you have two choices: either all birds can fly, in which
case you've defined "bird" to exclude Penguins, Ostriches, Emus, etc.,
or else some birds can't fly, in which case your base class is simply
wrong.

[ ... problems elided ]

> Which proves what? One more reason for making it a language issue.


I don't see a way to enforce this in a meaningful way at the language
level. You've simply specified a class invariant, and then violated it.
Ultimately, it seems to me that diagnosing such things requires
knowledge of the meaning of identifier involved to verify that (for
example) when you claim that all birds can fly that it's really
correct.

Even if that was possible, we probably wouldn't want it anyway. In most
cases, we're not looking for things that are necessarily true in
general, but simply that they're true to the extent necesary for the
job we're doing. As such, even if the compiler could enforce that our
names were completely accurate, we probably wouldn't want it to anyway.

--
Later,
Jerry.

The universe is a figment of its own imagination.


Matthias Kaeppler 04-01-2005 11:54 AM

Re: Possible encapsulation violation in C++
 
Jerry Coffin wrote:
> I don't see a way to enforce this in a meaningful way at the language
> level.


Java does, though indirectly. Access modifiers in Java are part of the
function signature, so a "private" fly() would /not/ be the allowed way
to implement the base class method:

interface Base {
public void fly();
}

class Derived implements Base {
private void fly() {}
}


override.java:6: fly() in Derived cannot implement fly() in Base;
attempting to assign weaker access privileges; was public
private void fly() {}

--
Matthias Kaeppler


All times are GMT. The time now is 07:23 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.