当调用类C++的方法时,类的"this"指向变为null

JLe*_*bbi 2 c++ pointers class this

我知道之前已经问过这个问题,但没有看到我的问题的正确解决方案,我的问题是,当我创建一个类的指针(PAGTexture)时,一切正常然后,该指针作为变量传递给另一个类,在那个新类(PAGRevolutionObject)中,我从PAGTexture调用一个方法,然后抛出一个异常.调试我意识到它实际进入该方法但"this"指针为空"0x00000000".这是我的PAGTexture的cpp:

#include "PAGTexture.h"

PAGTexture::PAGTexture()
{}

PAGTexture::~PAGTexture()
{
}

void PAGTexture::loadTexture(char * path_img, GLuint min_filter, GLuint mag_filter)
{
    int imgWidth, imgHeight;
    unsigned char *image;
    image = SOIL_load_image(path_img,
        &imgWidth,
        &imgHeight,
        0,
        SOIL_LOAD_RGBA);
    if (imgWidth == 0) {
        std::cout << "Failed to load image." << std::endl;
    }
    GLuint id_img;
    glGenTextures(1, &id_img);
    glBindTexture(GL_TEXTURE_2D, id_img);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imgWidth, imgHeight,
        0, GL_RGBA, GL_UNSIGNED_BYTE, image);
    glGenerateMipmap(GL_TEXTURE_2D);
    ep = id_img;
    id_imgs.push_back(id_img);
    SOIL_free_image_data(image);
}

void PAGTexture::applyTexture(GLuint id, int pos)
{
    glActiveTexture(id);

    glBindTexture(GL_TEXTURE_2D, id_imgs.at(pos));

}
Run Code Online (Sandbox Code Playgroud)

当调用"applyTexture"时它变成空指针,因为它试图从id_imgs.at(pos)获取id,而这个是null.

这就是我称之为"applyTexture"的部分:

GLuint t = 33984;
if (id_revol.size() != 0) {
    for (int i = 0; i < id_revol.size(); i++) {
        shader_used->setUniform("TexSamplerColor", i);
        textures->applyTexture(t + i, id_revol.at(i));
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,纹理不是空指针,因为我可以从那里访问"applyTexture".

这是我调试的图像: 图像调试过程

我还尝试设置一个数据断点,以了解我的代码的哪一部分使该指针在此"教程"之后被破坏但我无法为我的vs版本(VS2015)设置该断点.

说实话,我认为我的问题是我正在从另一个班级覆盖记忆(我的项目相当大)但即便如此我想要问一下我是否有遗漏的东西.

顺便说一句,我在调试模式下使用Visual Studio 2015(不是发布).

提前感谢您的回答.

EDIT1:根据我的要求,我定义了PAGTexture:

PAGTexture *texturesPack = new PAGTexture();
texturesPack->loadTexture("Textures/check.png", GL_LINEAR, GL_LINEAR);
texturesPack->loadTexture("Textures/HeadSpider.png", GL_LINEAR, GL_LINEAR);
texturesPack->loadTexture("Textures/wood.jpg", GL_LINEAR, GL_LINEAR);
objeto2->drawLowerBodySpiderAndHead(texturesPack);
Run Code Online (Sandbox Code Playgroud)

最后编辑:谢谢大家回答,我的问题是我在内联函数中绑定了指针,似乎你不能这样做(仍然不知道为什么),无论如何,我已经学到了一些点,我认为它可能很重要所以谢谢再次:D

Jea*_*bre 5

假设:"纹理不是空指针,因为我可以从那里访问"applyTexture"." 是错的.applyTexture它不是一个函数指针,它是一个类方法.

编译器实际上将对象表示法调用转换为:

PAGTexture::applyTexture(textures, t + i, id_revol.at(i));
Run Code Online (Sandbox Code Playgroud)

传递nullptr并不像编译器那样麻烦.但是在输入方法时,this==nullptr当您访问成员时它会崩溃.

它与数据成员(可能会立即崩溃)不同,因此您的困惑.

为了安全起见,你可以做以下事情:

void PAGTexture::loadTexture(char * path_img, GLuint min_filter, GLuint mag_filter)
{
     assert(this!=nullptr);
Run Code Online (Sandbox Code Playgroud)

如果使用空指针调用方法,则会因失败的断言而崩溃(注意:只有在关闭优化时才有效,否则编译器会认为即使使用优化this也不能)nullptr-O1

  • 值得一提的是,这是未定义行为的症状,不值得信赖。如果函数是虚拟的,大多数实现也会在调用之前崩溃(因为没有找到虚函数表)。 (2认同)