Why is privacy on a per-class basis but const doesn't work across objects of the same class?

75 Views Asked by At

I decided to try something out of curiosity to see how it would work. I got it into my head to see if one object of a class could access the private variables of another object of the same class. Apparently it can, if this program is any indicator:

#include <iostream>

using namespace std;

class Colour
{
private:
    int var;
public:
    void setVar(int x)
    {
        var = x;
    }
    int getVar() const
    {
        return var;
    }
    int getOtherVar(Colour col) //steals the private var of another Colour object
    {
        return col.var;
    }
};

int main()
{
    Colour green;
    Colour red;

    green.setVar(54);
    red.setVar(32);

    cout << "Green is " << green.getVar() << endl;
    cout << "Red is " << red.getVar() << endl;
    cout << "Green thinks Red is " << green.getOtherVar(red) << endl;


    return 0;
}

I was kind of expecting it to fail in a way where every unique instance of a class has access only to its own private members. I did some research and found out that privacy is a class-specific thing, not an instance-specific thing.

Anyways, I decided to experiment further and found something a bit confusing. I edited the implementation for getOtherVar() and turned it into this:

    int getOtherVar(Colour col) const
    {
        col.var = 67;
        return col.var;
    }

I figured that if objects can access each others members, shouldn't the const keyword protect other objects of the same class from change as well? It doesn't and I have no clue why.

3

There are 3 best solutions below

0
On BEST ANSWER

const member function makes const only an object for which you call that function, that is, *this. Namely, the "hidden" parameter this of that member function is a pointer-to-const. But this does not avoid modification of col parameter.

To make the other object const, simply pass it by const parameter. In your case, you would likely want to pass it by const reference:

int getOtherVar(const Colour& col) const
{
  col.var = 67;  // will not compile
  return col.var;
}

Passing by value will work with a copy of the function argument.


As for per-class access, if it was per-instance instead, how would you implement copy/move constructors and assignment operators? Or other functions, such as binary operators etc...

0
On

The current declaration of getOtherVar just ensures that the instance the method is called on remains const. If you wish to enforce that col cannot be modified you want

int getOtherVar(const Colour& col) const
{
    col.var = 67;    // <== this will not be allowed
    return col.var;
}
0
On

Consider the argument: when you design a class, you have full control over it's implementation. That means that there is not much sense in protecting the members of other objects of this class from yourself... The opposite is true for other classes, even the derived ones: that is something that someone else may develop. That is the reason to protect the members of YOUR class from the classes of OTHERS.

As for the const methods, the difference is in the hidden parameter this. While non-const methods have this parameter of type Class*, const methods have it of type const Class*. This rule doesn't affect the other arguments that may be mutable even if they are of the same class.