Accessing private members [closed]

Solution 1:

Let's not consider ethics for a moment. Let's consider the standard.

What you are proposing to do is nonstandard. See section 9.2, clause 12 of the standard. "The order of allocation of nonstatic members separated by an access-specifier is unspecified." Therefore, if you have a class with private members, and a struct with no private members, the standard does not guarantee that the members will be in the same order.

Therefore, if your hack works, it works only by accident, that the compiler writers happened to do it that way. There is no guarantee that it will work on another compiler, a later version of the same compiler, or with different class layouts.

Not to mention that, if you don't have authority to modify the class (say, to provide a simple accessor function), you probably don't have authority to object if any implementation detail in the class changes. (One of the ideas behind public and private is to distinguish what is promised from what is freely changeable.) Therefore, the layout may change, or the member might come to mean something different, or be removed altogether.

Herb Sutter wrote a Guru of the Week column on this issue.

Oh, as far as the ethics go? If you really, really have to do something like this, and you can't get out of it, document it very carefully. If your coding standards have some sort of procedure to flag nonstandard behavior, use them. If not, be very careful to note it in a way it won't be overlooked when something goes wrong.

Solution 2:

I'm not sure that "ethics" really come into it. It busts the heck out of encapsulation though.

EDIT: I would almost never accept this if I were performing a code review. You'd have to work really hard to convince me there's no way of designing around the need for this. It's possible you'd succeed, but there'd have to be major warnings all over the place, and rock hard unit tests to make sure that if anything changed to break it, you'd know quickly.

Solution 3:

I've just added an entry to my blog that shows how it can be done in a completely conforming way. Here is an example on how you use it for the following class

struct A {
private:
  int member;
};

Just declare a tag name and instantiate a robber like the following example shows (my post shows the implementation of the robber). You can then access that member using a member pointer

struct Amem { typedef int type; };
template class rob<Amem, &A::member>;

int main() {
  A a;
  a.*result<Amem>::ptr = 42; // Doh!
}

But actually, this doesn't show that c++'s access rules aren't reliable. The language rules are designed to protect against accidental mistakes - if you try to rob data of an object, the language by-design does not take long ways to prevent you.


The above is a way to access private and protected members in a conforming way. This one is another way to access protected members in a Standard conforming way. The basic idea is to use a member pointer

std::deque<int> &getAdapted(std::stack<int> &s) {
    struct voyeur : stack<int> 
    { using stack<int>::c; };
    return s.*(&voyeur::c);
}

int main() {
    std::stack<int> s;
    std::deque<int> &adapted = getAdapted(s);
    output(adapted); // print the stack...
}

No casting or type punning involved. It takes a pointer to a protected member of std::stack<int> through a class derived from it where that member name is public, so the compiler allows this. Then it uses it on a std::stack<int> object, which is allowed too.

Solution 4:

I have had this happen to me since there was a very crappy source control system in place where for old versions of the application making changes to header files was pretty much impossible.

If some cases you just need to do a hack.

In the source file from which you need to access the private data member you can put in this as a first line:

#define private public
#define protected public

and access anything you want.

Solution 5:

No. What you are doing is Pure Evil.