0

My friend made this code that will access the memory of class and change the value of a private variable.

#include <iostream>

using namespace std;

class has_private_variable
{
private:
    const int member1;
public:
    has_private_variable()
    : member1(5) //initializer list. In case you haven't seen that before
    {
    }
    int getMember1()
    {
        return member1;
    }
};

int main()
{
    has_private_variable hpv;
    int tmp = hpv.getMember1();
    cout << hpv.getMember1() << endl;
    char* ptr = (char*)&hpv; //Yeah this will generate all types of warnings hopefully
    //find the actual address of the member
    while (*(int*)ptr != tmp)
        ptr++;
    int* ptr_int = (int*)ptr;
    *ptr_int = 3;
    cout << hpv.getMember1() << endl;
    //There's a joke in here about hpv.vaccinate(), but I can't be bothered to find it
    return 0;
}

The ability to do this seems like it destroy the entire point of having a private variable. Is there some method to stop a programmer from being able to access a private variable like so?

Edit:

From the comments I'm getting, my friend is invoking undefined behavior of C++. But is there someway to it so that a programmer may not be able to do this?

Community
  • 1
  • 1
Sahar Rabinoviz
  • 1,939
  • 2
  • 17
  • 28
  • 5
    To cite @Jerry Coffin: "C++ attempts to protect against accidents, not intentional subversion (aka "protects from Murphy, not Machiavelli")." – vsoftco Nov 21 '14 at 18:55
  • Or: C++ does not prevent you from doing whatever you want (what must be done). It only warns you if it looks dangerous and you didn't assert you are right. – Deduplicator Nov 21 '14 at 18:59
  • Your friend has invoked undefined behaviour, which by pure chance had the effect of accessing a private variable. [Read about undefined behaviour here](http://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior). – n. m. could be an AI Nov 21 '14 at 19:54
  • @Deduplicator he used g++ -Wall 4.8.3 and got no warns – Sahar Rabinoviz Nov 21 '14 at 20:04
  • So? That cast is an explicit request to shut the hell up and soldier on. Anyway, better use `-std=c++14 -Wall -Wextra -pedantic`. – Deduplicator Nov 21 '14 at 20:06
  • I'm surprised this even works due to alignment issues. – Paul J. Lucas Nov 21 '14 at 22:29

1 Answers1

0

It could be possible using a dedicated template class, the template class makes a private member and allocates it statically in an hidden memory location:

template<typename type>
class true_private
{
public:
    ~true_private()
    {
       type local;
       get_set(-1, local);
    }

    true_private(type value)
    {
       type local = value;
       get_set(0, local);
    }

    void get_set(int op, type& value)
    {
        static type* var = 0;

        if( var == 0)
            var = new type();

        if( op == 0 ) // set
            *var = value;

        else if(op == 1) // get
            value = *var;
        else  // delete
            delete var;
    }

    type Get()
    {
        type local;
        get_set(1, local);
        return local;
    }

    void Set(type value)
    {
       type local = value;
       get_set(0, local);
    }
};

class has_private_variable
{
private:
     true_private<int> member1;
public:
    has_private_variable()
    :member1(5) //initializer list. In case you haven't seen that before
    {
    }
    int getMember1()
    {
        return member1.Get();
    }
};

This is just an exercise to show the power of template class :)

AngeloDM
  • 397
  • 1
  • 8