Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 访问'的私人成员;这';静态成员函数中的指针_C++_C++11 - Fatal编程技术网

C++ 访问'的私人成员;这';静态成员函数中的指针

C++ 访问'的私人成员;这';静态成员函数中的指针,c++,c++11,C++,C++11,我刚刚发现了一些与我所知道的语言相矛盾的东西。让我们从以下状态开始: 此类指针的类型为:class*const 无法访问对象的私有成员(除好友类对象外) 静态方法无权访问对象数据 因此,如果没有注释,下面的代码将无法编译: class Foo{ public: Foo* getPtr(){ return this; } private: int m_id; }; int main(int argc, char **argv) { Foo f

我刚刚发现了一些与我所知道的语言相矛盾的东西。让我们从以下状态开始:

  • 类指针的类型为:
    class*const
  • 无法访问对象的私有成员(除好友类对象外)
  • 静态方法无权访问对象数据
因此,如果没有注释,下面的代码将无法编译:

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
}
这个
指针可以像普通指针一样传递给函数,对吗

那么,当私有数据作为参数传递给静态函数回调时,为什么可以通过
这个
指针访问私有数据呢?什么样的语言规则允许它

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;
}
类胃{
公众:
使用OnDigested=void(*)(void*userData);
void开始测试(void*userData){
计时器(std::chrono::秒(1),m_onDigested,userData);
}
无效设置无效(无效设置无效设置无效设置){
m_onDigested=onDigested;
}
私人:
未消化的m_未消化的;
};
类动物{
公众:
动物(标准:弦类){
m_物种=物种;
}
空檐{
m_胃。设置消化(消化);
m_胃开始(这个);
}
私人:
静态void OnDigested(void*userData){
动物*动物=静态施法(用户数据);

std::难道这是语言的规则,说私有类成员可以从任何类方法访问。一个
静态
类方法仍然是一个类方法。编译器的私有性和公共性规则是关于编译器的编译时逻辑。这不是关于运行时逻辑,它是关于编译应用程序的问题,不是吗t编译器。
static\u cast
基本上是围绕内存地址偏移量的廉价运行时调用,无法自行决定在将指针转换为
void
指针类型之前,指针是指向私有数据还是指向公共数据。换句话说,转换为
void
指针。要扩展@SamVarshavchik所说的内容:您还可以从成员函数中的同一类的不同对象访问私有成员。您可能见过这样的代码
bool operator==(const class&c)const{return this->val==c.val;}
其中
val
类的私有成员。