2014-11-21 8 views
0

Мой друг сделал этот код, который получит доступ к памяти класса и изменит значение частной переменной.C++ доступ к классу памяти и изменение личной переменной

#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; 
} 

Умение делать это похоже на то, что оно уничтожает всю точку с частной переменной. Есть ли способ остановить программиста от доступа к частной переменной?

Edit:

Из комментариев я получаю, мой друг вызывая неопределенное поведение C++. Но может ли быть так, чтобы программист, возможно, не смог этого сделать?

+5

Процитировать @ Jerry Coffin: «C++ пытается защитить от несчастных случаев, а не преднамеренную подрывную деятельность (иначе« защищает от Мерфи, а не Макиавелли »)». – vsoftco

+0

Или: C++ не мешает вам делать то, что вы хотите (что должно быть сделано). Он только предупреждает вас, если он выглядит опасным, и вы не утверждали, что правы. – Deduplicator

+0

Ваш друг вызвал неопределенное поведение, которое по чистой вероятности привело к доступу к частной переменной. [Читайте о неопределенном поведении здесь] (http://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior). –

ответ

0

Это может быть возможно с помощью специального шаблонного класса, класс шаблона делает частный элемент и выделяет его статический в скрытом месте памяти:

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(); 
    } 
}; 

Это просто упражнение, чтобы показать силу шаблонного класса :)