Search code examples
c++oopclassreinterpret-cast

Class Private members modified on creating a structure (C++)


I was just going through some codes of C++. Where in I came across the concept of reinterpret_cast operator.

EDIT 1 :

I know that accessing private members of a class is not recommended. But in some situations we ought to go ahead and access them. I have just put forth this question to get my concepts clear.

In the example that I referred,the private member of the Class is accessed by simply creating a structure with the same variables and then later on modified by implementing reinterpret_cast operator.

I have understood the usage of reinterpret_cast operator,as in I know what it does,but I fail to understand how a structure could be used to modify the values of a private Class member.

Following is the source code which I referred:

Class:

class Student
{
public:
    explicit Student(float percent) // Cannot be used for conversion
    {
        static int nid;

        id = ++nid;
        score = percent;
    }

    int Id() const
    {
        return id;
    }

    float GetScore() const
    {
        return score;
    }

    void SetScore(float value)
    {
        score = value;
    }

    virtual ~Student(){}

private:
    int id;
    float score;
};

Structure used to access and modify private class members:

struct _Student
    {
        void* vptr;
        int id;
        float score;
    };

    _Student* bs3 = reinterpret_cast<_Student*>(bs2);
    bs3->id = 5;

Thank you.Please correct me if I'm wrong/I couldn't put forth my question in an appropriate manner.


Solution

  • $5.2.10/2 - "An expression of integral, enumeration, pointer, or pointer-to-member type can be explicitly converted to its own type; such a cast yields the value of its operand."

    This means that pointers 'bs2' and 'bs3' are pointing to the same location

    $9.2/16 - "Two standard-layout struct (Clause 9) types are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in declaration order) have layout-compatible types (3.9)."

    This means that your class and struct are layout compatible.

    $9/6-

    A standard-layout class is a class that:

    — has no non-static data members of type non-standard-layout class (or array of such types) or reference,

    — has no virtual functions (10.3) and no virtual base classes (10.1),

    — has the same access control (Clause 11) for all non-static data members,

    — has no non-standard-layout base classes,

    — either has no non-static data members in the most-derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and

    — has no base classes of the same type as the first non-static data member.108

    Since your class has a virtual destructor, your class and struct are not standard layout classes.

    However you have added a 'void *' data member to possibly take care of the 'vptr' (thereby possibly mimicking layout compatibility based on your particular compiler implementation)

    In this case reinterpret_cast is used to interpret the class pointer (bs2) as a struct pointer (bs3). By default struct members are public. Since the return value of reinterpret cast points to the same memory (refer quote above) where class members are located, you can modify the struct members (which are the same as the original class members).

    This is cheating. This is highly discouraged.! This is most likely going to lead to undefined behavior