samedi 30 novembre 2019

Accessing to a private member of 'this' pointer in a static member function

I've just discovered something that was in contradiction to what I knew about the language. Let's start with following statemets:

  • this pointer of a class has type: Class* const
  • accessing private members of an object is not possible (except friend class objects)
  • a static method does not have access to object data

So the code below would not compile if not commented:

class Foo{
public:
    Foo* getPtr(){
        return this;
    }

private:
    int m_id;
};

int main(int argc, char **argv)
{
    Foo foo;
    Foo* fooPtr = foo.getPtr();
//    fooPtr->m_id; Won't compile
}

this pointer can be passed around to functions like a regular pointer, right?

So why it is possible to access private data through this pointer when it's passed to the static function callback as a parameter? What rule of the language allows it?

class Stomach{
public:
    using OnDigested = void (*)(void* userData);

    void StartEating(void* userData){
        timer(std::chrono::seconds(1), m_onDigested, userData);
    }

    void SetOnDigested(OnDigested onDigested) {
        m_onDigested = onDigested;
    }
private:
    OnDigested m_onDigested;
};

class Animal{
public:
    Animal(std::string specie){
        m_specie = specie;
    }

    void StartLeave(){
        m_stomach.SetOnDigested(OnDigested);
        m_stomach.StartEating(this);
    }
private:
    static void OnDigested(void* userData){
        Animal* animal = static_cast<Animal*>(userData);

        std::cout << "Every eaten tiger makes me wonder who I am.."
                     " I must be a: " << animal->m_specie << std::endl;

//        std::string specie = m_specie; //Won't compile
    }

    Stomach m_stomach;
    std::string m_specie;
};

int main(int argc, char **argv)
{
    Animal mammoth("Mammoth");
    mammoth.StartLeave();

    return 0;
}

The code above compiles and prints "Every eaten...".

I know that the call to the m_specie member is done from a Animal class, but not from an instance of animal class (static function). I assumed that when a this pointer is passed using userData it could be used as any other pointer (without access to private members)

Aucun commentaire:

Enregistrer un commentaire