Reputation: 103
#include<iostream>
using namespace std;
class A
{
int value;
public:
A(){value = 1;}
~A(){}
void print(){cout << value << endl;}
};
int main()
{
A a;
int* p = (int*)(&a);
*p = 20;
a.print();//output is 20.
}
Does not this break a class's encapsulation? I'm a beginner of c++. I have never seen this method that can access to a class's private member in the book "c++ primer".
Upvotes: 2
Views: 497
Reputation: 14967
Your code is essentially undefined behavior. By the following lines:
int* p = (int*)(&a);
*p = 20;
you are dereferencing a type-punned pointer, despite the fact that such type-punning does not respect the strict aliasing rules. For a correct version of your code, A
should be an aggregate type, see Type aliasing section here. In your code, A
is practically not an aggregate type, since it contains a private member. See the definition of an aggregate type here.
Upvotes: 1
Reputation: 20990
This is allowed because A
is a standard_layout class, which is a class that is compatible with the layout of other languages, meaning it can be passed to functions that have been written in something other than C++. It breaks encapsulation but this isn't something you generally want to do in C++ land, it's a compatibility feature.
Since you're a beginner however, you almost certainly want to avoid doing anything that involves using c-style casts / reinterpret_cast
. Trust the type system and access controls, they're there to help you - if you override them you'll need to know exactly why, which obviously wasn't the case here.
Upvotes: 2