Why Does C++ Allow Private Members to Be Modified Using This Approach

Why does C++ allow private members to be modified using this approach?

Because, as Bjarne puts it, C++ is designed to protect against Murphy, not Machiavelli.

In other words, it's supposed to protect you from accidents -- but if you go to any work at all to subvert it (such as using a cast) it's not even going to attempt to stop you.

When I think of it, I have a somewhat different analogy in mind: it's like the lock on a bathroom door. It gives you a warning that you probably don't want to walk in there right now, but it's trivial to unlock the door from the outside if you decide to.

Edit: as to the question @Xeo discusses, about why the standard says "have the same access control" instead of "have all public access control", the answer is long and a little tortuous.

Let's step back to the beginning and consider a struct like:

struct X {
int a;
int b;
};

C always had a few rules for a struct like this. One is that in an instance of the struct, the address of the struct itself has to equal the address of a, so you can cast a pointer to the struct to a pointer to int, and access a with well defined results. Another is that the members have to be arranged in the same order in memory as they are defined in the struct (though the compiler is free to insert padding between them).

For C++, there was an intent to maintain that, especially for existing C structs. At the same time, there was an apparent intent that if the compiler wanted to enforce private (and protected) at run-time, it should be easy to do that (reasonably efficiently).

Therefore, given something like:

struct Y { 
int a;
int b;
private:
int c;
int d;
public:
int e;

// code to use `c` and `d` goes here.
};

The compiler should be required to maintain the same rules as C with respect to Y.a and Y.b. At the same time, if it's going to enforce access at run time, it may want to move all the public variables together in memory, so the layout would be more like:

struct Z { 
int a;
int b;
int e;
private:
int c;
int d;
// code to use `c` and `d` goes here.
};

Then, when it's enforcing things at run-time, it can basically do something like if (offset > 3 * sizeof(int)) access_violation();

To my knowledge nobody's ever done this, and I'm not sure the rest of the standard really allows it, but there does seem to have been at least the half-formed germ of an idea along that line.

To enforce both of those, the C++98 said Y::a and Y::b had to be in that order in memory, and Y::a had to be at the beginning of the struct (i.e., C-like rules). But, because of the intervening access specifiers, Y::c and Y::e no longer had to be in order relative to each other. In other words, all the consecutive variables defined without an access specifier between them were grouped together, the compiler was free to rearrange those groups (but still had to keep the first one at the beginning).

That was fine until some jerk (i.e., me) pointed out that the way the rules were written had another little problem. If I wrote code like:

struct A { 
int a;
public:
int b;
public:
int c;
public:
int d;
};

...you ended up with a little bit of self contradition. On one hand, this was still officially a POD struct, so the C-like rules were supposed to apply -- but since you had (admittedly meaningless) access specifiers between the members, it also gave the compiler permission to rearrange the members, thus breaking the C-like rules they intended.

To cure that, they re-worded the standard a little so it would talk about the members all having the same access, rather than about whether or not there was an access specifier between them. Yes, they could have just decreed that the rules would only apply to public members, but it would appear that nobody saw anything to be gained from that. Given that this was modifying an existing standard with lots of code that had been in use for quite a while, the opted for the smallest change they could make that would still cure the problem.

why does the derived class inherit the private members of the base class?

The derived class needs the private members even though it can't access them directly. Otherwise it's behavior would not build on the class it is deriving from.

For example, pretend the private stuff is:

int i;

and the class has a geti() and seti(). The value of i has to be put somewhere, even if it is private,

(C++ )If I declare something private in a class but it can be changed via public methods of class, then why should I declare it private?

This is the idea and principle of private data - public interface, whereby the public method used to change any private fields has suitable and appropriate defenses against altering the private fields to an unwanted value in the program (i.e. to avoiding the breaking of any invariants). If the field was simply public then there would be no such defense against this.

What is the difference between private and protected members of C++ classes?

Private members are only accessible within the class defining them.

Protected members are accessible in the class that defines them and in classes that inherit from that class.

Edit: Both are also accessible by friends of their class, and in the case of protected members, by friends of their derived classes.

Edit 2: Use whatever makes sense in the context of your problem. You should try to make members private whenever you can to reduce coupling and protect the implementation of the base class, but if that's not possible then use protected members. Check C++ FAQ for a better understanding of the issue. This question about protected variables might also help.

Should I use public or private variables?

private data members are generally considered good because they provide encapsulation.

Providing getters and setters for them breaks that encapsulation, but it's still better than public data members because there's only once access point to that data.

You'll notice this during debugging. If it's private, you know you can only modify the variable inside the class. If it's public, you'll have to search the whole code-base for where it might be modified.

As much as possible, ban getters/setters and make properties private. This follows the principle of information hiding - you shouldn't care about what properties a class has. It should be self-contained. Of course, in practice this isn't feasible, and if it is, a design that follows this will be more cluttered and harder to maintain than one that doesn't.

This is of course a rule of thumb - for example, I'd just use a struct (equivalent with a class with public access) for, say, a simple point class:

struct Point2D
{
double x;
double y;
};

A private variable can be accessed from another object of the same type?

Methods of a class can access its private attributes throughout all class instances, at least in C++.

Are there any reasons to use private properties in C#?

I use them if I need to cache a value and want to lazy load it.

private string _password;
private string Password
{
get
{
if (_password == null)
{
_password = CallExpensiveOperation();
}

return _password;
}
}


Related Topics



Leave a reply



Submit