Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Using pointer, I am able to modify the private value of the class in the code below.

Does it violate the C++ concept that private member can only be modified by member or friend functions?

#include<iostream>
using namespace std;

class demo
{
        private: int info;

        public:
                 demo()
                 {
                         info=10;
                 }

                 void print_info()
                 {
                       cout<<info;
                 }
};

int main()
{

     demo ob;
     int* ptr=(int*)&ob;

     *ptr=20;

     ob.print_info();

     return 0;
}
share|improve this question
1  
isn't reinterpreting pointers like that a recipe for undefined behavior? –  ratchet freak Aug 9 '13 at 11:12
    
Using reflection, you can modify private members in languages like C# and Java. In both cases, you are going out of your way to poke at the data structures. Like Bart said, access modifiers are meant to protect you from accidents, nothing more. After all, it's all your process' memory, and what your process does with it is really nobody else's concern. –  Michael Kjörling Aug 9 '13 at 11:33
1  
But the C# variant is a bit different since low trust code can't use it. C++ on the other hand only knows fully trusted code. –  CodesInChaos Aug 9 '13 at 11:36

4 Answers 4

The C++ mechanism of public, protected and private members is meant to protect you from accidents, not from malicious intent.

Re-interpreting a pointer as if it points at something else (like you do with int* ptr=(int*)&ob) counts as 'malicious intent' and usually means that you are stepping beyond the C++ language. What happens is entirely up to the compiler and it does not have to be consistent in what it does.


Note that there are other ways to expose private data, for example:

class demo
{
    private: int info;

    public:
             demo()
             {
                     info=10;
             }

             int* expose_info()
             {
                    return &info;
             }
};

This is entirely legal in C++ (although usually a bad idea). The public/protected/private mechanism works only on names (so the name info is inaccessible for outsiders), but if you can get your hands on a pointer/reference to a private member, you have full access to that member.

share|improve this answer

Access descriptors in C++ are a static mechanism. Compliance is checked at compile time by the compiler, and no memory of the privacy level of methods or attributes is retained at run time, nor are any checks performed by then.

By using a C-style cast you are completely circumventing C++ static checks and all bets are off.

share|improve this answer
1  
I would add that using any kind of cast (c-style or c++ style) tells the compiler that you, the programmer, are smarter than the compiler. You are telling the compiler "trust me, I know what I am doing." Umm, yeah. –  Bill Door Aug 9 '13 at 16:22
    
True. By singling out the C-style cast I just meant that it's a particularly strong type of cast... you are basically shouting "I know what I am doing!" :) –  UncleZeiv Aug 9 '13 at 17:56

The exact posted code has has defined behavior under c++11, since demo is a standard-layout class and info (the data member) is accessed as a compatible type, but it is bad style.

Standard-layout class must:

  • Have the same access control for all data members
  • Have no virtual functions
  • Only inherit from standard-layout classes
  • At most one class in its class hierarchy has data members
  • Has no data members with the same type as any in the class hierarchy

This text is simplified from 9.7 of the draft standard. In my terminology, class hierarchy includes the class itself, and data members only covers non-static data members.

Accessing the data member with an incompatible type would cause undefined behavior, as always. For instance short is undefined, but char and int is defined.

In short, such access is defined if the class is standard-layout . So be VERY careful. You can check if a type is standard-layout with std::is_standard_layout

share|improve this answer

This has been happening accidentally for years via buffer overflows, bad aliases, and other pointer errors. You write memory past the bounds of an array, and viola! you are corrupting the (possibly private) memory in another object. You are using a pointer that has been de-allocated elsewhere, then another process creates an object at that address and viola!, you are corrupting memory. The accessibility features of C++ are for writing contracts and separating concerns in your design for your users. Just like in C# and JAVA, it doesn't prevent anyone--most likely yourself accidentally-- from misusing pointers.

On a side note, you can also use memcpy to copy one class to another using the same exact idea. You should never actually do that in production code, but it can easily be done.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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