3

I was going through a question and here the answer says that Encapsulation is being violated

class car
{ 
    int speed;
    public : int* getSpeed()
    { 
        return &speed; 
    }
};

int main()
{
    car c;
    int *ptr=c.getSpeed();
    return 0;
}

But I really don't see how that is happening. Getters and Setters actually provide encapsulation.

2
  • 4
    Where is the question whose answer says that? – geocodezip Jul 4 '20 at 3:08
  • Information crosses borders all the time. The proper questions to ask are: (1) What is the goal? What tasks need to be done? What is to be accomplished? and (2) How to accomplish that, while minimizing the possibility of misuse (e.g. "encapsulation violation") – rwong Jul 4 '20 at 19:49
11

Returning a pointer to an internal variable of a class is an encapsulation violation, once you have that pointer, you can modify the speed variable inside of car.

To avoid that, return the value of speed.

class car
{ 
    int speed;
    public : int getSpeed()
    { 
        return speed; 
    }
};
9
  • 1
    In an ideal world nothing but car would ever know the value of speed. So this is still a violation. It's just not as nasty since you can now set a breakpoint and see when the encapsulation is being violated. – candied_orange Jul 4 '20 at 7:49
  • 3
    @candied_orange I use my encapsulated car as a black box. I know nothing about its internals, but I can nevertheless read the speed on the tacho. It's part of the expectations for any car to provide for speed information in its interface. I think that int getSpeed() is exactly that, and totally legit. It doesn't break encapsulation, since I could tomorrow decide to represent internally the speed completely differently and make a calculation (e.g. int angular_velocity, wheel_diameter; ). – Christophe Jul 4 '20 at 11:37
  • @Christophe that's as bad as claiming it's ok to make the speed attribute public because you never use it. Even in python that wouldn't be ok. – candied_orange Jul 4 '20 at 11:41
  • 3
    @candied_orange so, how could an external class interact with the Car if it isn't allowed to ask any information? Take the example of a simulation engine: how could you update the position of the Car if the Car can't be asked for its speed, if the Car doen's know anything about topology, and no class bcould ask neither the Map nor the Car the current position? – Christophe Jul 4 '20 at 11:47
  • 1
    @candied_orange thank you, but I still didn't get how a car do anything useful in interaction with other objects, in absence of any mutual feedback because every object is only allow to do things. How does the car know that going straight away it will reach the end of the street and crash into a house, if neither the street nor the house can tell their position and the car does'nt know its own? But there may be a misunderstanding here: OP doesn't ask about the principle of least knowledge, but about encapsulation, i.e. providing a public interface and isolating the internal details. – Christophe Jul 4 '20 at 12:08
5

geocodezip's answer is correct.

Any class member exposed through public functions as a non const reference (pointers are just another form of reference) violates encapsulation.

There are more ways to guarantee encapsulation besides the code shown by geocodezip:

  • Use a const pointer

    public : const int* getSpeed() {
          // ^^^^^ prevents the value of speed getting changed through the pointer
          return &speed; 
    }
    
  • Use a const reference

    public : const int& getSpeed() {
          // ^^^^^ prevents the value of speed getting changed through the reference
          return speed; 
    }
    

Using these from above won't have much impact with a simple int variables, but may have advantages for more complex scenarios.

E.g. the pointer variant allows to return a nullptr to indicate that there's an optional or uninitialized value.

In a similar manner const references allow to return something like an empty value type instead of the direct reference to the member (such things like empty value types should follow the Flyweight Design Pattern).

7
  • The const pointer or reference have the advantage of avoiding the external world to interfere in internal business of the class. It nevertheless weakens the encapsulation since it forces you to maintain internally an int so that you can return its reference. Furthermore, it forces you to always maintain this int, because once the reference is out, it could be used anytime. – Christophe Jul 4 '20 at 11:41
  • @Christophe I don't (fully) get your point. Isn't the main goal to prevent directly changing the data from outside of the class? Using the const variants just allow to directly observe how data is changed inside of that class. But you're right insofar, that those references need to refer to some particular data member maintained inside of the class. – πάντα ῥεῖ Jul 4 '20 at 11:48
  • In my original comment I was asking about behaviour of removing the const-ness using const_cast and then changing the value after. I eventually tried it in a sandbox and the internal value is indeed changed, so protecting the internal value using a const reference is not completely safe. Working example is available here. – Andy Jul 4 '20 at 16:50
  • @Andy A cast would remove the constness, but that's something that should never be done. At least you can almost always undermine intended behaviors. – πάντα ῥεῖ Jul 4 '20 at 16:51
  • 1
    @Andy Something like that, yes. – πάντα ῥεῖ Jul 4 '20 at 16:58
0

By returning a pointer to the private member of the class you are violating the encapsulation. Now anyone can access that memory location using pointer which shows contradicting behavior. Encapsulation means hiding data, Getters and setters don't always give encapsulation. If you want encapsulation then you have to use getters and setters in a specific way such data nothing in world can access your class members.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.