Prevent the programmer from using any trick to access a private class member

By declaring a private part of a member, a non-friend function cannot directly access that member. But there is a way to access them using the pointer-type, for example:

class Foo {

  private:
    int value;

  public:
    inline int get() {
      return value;
    }
    inline Foo (int value) {
      Foo::value = value;
    }

} foo(1234);

int main() {
  using namespace std;
  cout << foo.display() << endl; // display 1234
  int *p = (int *)(&foo); // HERE!
  *p = 5678;
  cout << foo.display() << endl; // display 5678, foo.value has been changed
  return 0;
}

      

Can we prevent the user from using these tricks? Or can we disable the conversion Foo *

to int *

?

+3


source to share


3 answers


No, it is possible that a certain programmer will not be able to perform an explicit type conversion, since there are almost unlimited ways that a certain enough programmer can implement, especially if he wants to accept potential undefined behavior.

Philosophically, a C ++ type system is generally designed to make it harder to do things by accident. However, it is not intended to prevent the programmer from deliberately undermining the type system.

Something harder can be done with method combinations:



  • Use the pimpl idiom (already mentioned in parapura rajkumar's answer)
  • Add offset for members (including from pimpl). It is not necessary for the programmer to be obvious that the implementation details may be offset by, for example, 18 bytes.
  • Supply a private operator&()

    for your class, which will have the effect of preventing use &object

    to get the address of an object.
  • Do not provide member functions that return this

    or return the address (or references to) any private or protected class data. And they do not have publicly available data.

The point is that a fairly specific programmer will find a way to get around all sorts of tricks like this, even without accessing the source code. Tricks like this also have the unfortunate effect of making it more difficult for developers to use their class in more conventional ways that you might intend.

+4


source


One option is to use PIMPL and never include implementation class headers as part of your library.

class A
{
    Aimpl* a_;
public:
    int getValue();
};

      



Users can now access, but never know the internal components of Aimpl to change it.

+2


source


You cannot prevent anyone from writing seemingly valid and working code as you show.

It looks like because

 *p = 5678;

      

is actually undefined behavior and cannot be relied upon to provide the same results as yours.

0


source







All Articles