473,396 Members | 1,998 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,396 software developers and data experts.

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

Jul 23 '05 #1
12 1563


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


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

Jul 23 '05 #2

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.

Jul 23 '05 #3


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.
Jul 23 '05 #4
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
Jul 23 '05 #5
On 31 Mar 2005 05:21:36 -0800, chintoo <ab******@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.
Jul 23 '05 #6
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
Jul 23 '05 #7
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
Jul 23 '05 #8
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.

Jul 23 '05 #9
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
Jul 23 '05 #10
> No all you have done is fuxored the is-a relationship.

I didn't get what you mean..please explain
Jul 23 '05 #11
Matthias Kaeppler wrote:
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:


Unfortunately, this is the opposite of what I was talking about. I was
talking about it preventing you from putting a "fly" member in a class
named "bird" in the first place. This makes you claim that a Penguin
really CAN fly.

Java is enforcing consistent lies, not honesty.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 23 '05 #12
Matthias Kaeppler wrote:
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:


That is, in a sense, a hack of what you really want though. NOt all birds can
fly and a Penguin having a method to fly, regardless of access, just seems
wrong. The fact tht not all birds can fly means having a public fly() method
in he Bird class is even worse. A better way would be like this:

class Bird {
public:
virtual ~Bird();
};

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

class Blackbird : public FlyingBird {
public:
void fly();
}

class Penguin : public Bird {
....
}

Now you have an IS-A rleationship between all bird-types as Bird, and one for
flying birds as FlyingBird. This then allows you to do:

void flyBird(Bird& b)
{
// attempt to cast b to a FLyingBird. If not able to fly, throw std::bad_cast
FlyingBird& fb = dynamic_cast<FlyingBird&>(b);
fb.fly();
}
Jul 23 '05 #13

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

Similar topics

6
by: J Smith | last post by:
After doing some googling through the lists and such, I wasn't able to arrive at a solution for a problem I've run into recently. I've seen mention of similar symptoms, but my case seems different....
3
by: K.K. | last post by:
Consider the following code: >>>>>>>>>>> // Define an empty class public class ZorgleCollection : Dictionary<string, Zorgle> { } // Somewhere outside ZorgleCollection:
3
by: enchantingdb | last post by:
I have an exam tomorrow that covers the perceived advantages and disadvantages of object oriented programming, in particular polymorphism, inheritance and encapsulation. I know the advantages but...
11
by: Brent Ritchie | last post by:
Hello all, I have been using C# in my programming class and I have grown quite fond of C# properties. Having a method act like a variable that I can control access to is really something. As...
5
by: jmsantoss | last post by:
Hi, This is a design question. I have a class named "DataBuffer" that stores some data. After "DataBuffer" is created it can not be modified. All the methods of "DataBuffer" are const as data...
47
by: Roger Lakner | last post by:
I often see operator implemented something like this: class Foo { ... }; class FooList { public: const Foo& operator (unsigned index) const {return array;}; Foo& operator (unsigned index) ...
32
by: bluejack | last post by:
Ahoy: For as long as I've been using C, I've vacillated on the optimal degree of encapsulation in my designs. At a minimum, I aggregate data and code that operate on that data into classlike...
16
by: copx | last post by:
I have recently read "Everything you ever wanted to know about C types" by Peter Seebach (1), and learned about incomplete types. Now, I realise the value of encapsulation, but I wonder whether it...
2
by: subramanian100in | last post by:
Is my following understanding correct ? Data abstraction means providing the interface - that is, the set of functions that can be called by the user of a class. Information hiding means...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.