binbin
binbin

Reputation: 103

Why does c++ allow access to a class's private member through a pointer?

#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

Answers (2)

Lingxi
Lingxi

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

user657267
user657267

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

Related Questions