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.