C++ C++&引用;“无法读取内存”;从继承的类访问指针对象时

C++ C++&引用;“无法读取内存”;从继承的类访问指针对象时,c++,pointers,inheritance,C++,Pointers,Inheritance,我有一个错误: Exception thrown at 0x0108C6E9 in myprojectname.exe: 0xC0000005: Access violation reading location 0x00000028. 但是,只有在通过派生类从基类调用函数时才会发生这种情况 派生类: #pragma once #include "Player.h" class Space; class Enemy : public Player{ public: void init

我有一个错误:

Exception thrown at 0x0108C6E9 in myprojectname.exe: 0xC0000005: Access violation reading location 0x00000028.
但是,只有在通过派生类从基类调用函数时才会发生这种情况

派生类:

#pragma once
#include "Player.h"

class Space;
class Enemy : public Player{
public:
    void init(Space * s);

private:
    //Space * space = nullptr;
};
CPP文件:

#include "Space.h"
#include "Enemy.h"
#include "Player.h"

void Enemy::init(Space * s) {
    //space = s;
}
我需要一个指向空间对象的指针,因为我的基类也需要它。我不确定是否需要这样做

以下是我如何调用基本(玩家)类的函数:

错误消息“无法读取内存”发生在基类需要的类(例如指向窗口的指针)的getter函数中

有人知道我做错了什么吗

编辑

我忘了告诉:我在项目的每个类中初始化了指向名为space的导入类的空间指针。如果我不调用敌方类继承的东西,这个程序可以很好地处理这些空间指针

空间.h

#pragma once
#include "Window.h"
#include "Game.h"
#include "Input.h"
#include "Text.h"
#include "Player.h"
#include "Enemy.h"

#include <ctime>

class Space {
public:
    void init();
    int getStartTime();

    Window & getWindow();
    Game & getGame();
    Input & getInput();
    Text & getText();
    Player & getPlayer();
    Enemy & getEnemy();

private:
    Text textObj;
    Window windowObj;
    Game gameObj;
    Input inputObj;
    Player playerObj;
    Enemy enemyObj;

    int startTime = clock();
};
Player.h(具有空格指针):

Player.cpp:

#include "Player.h"
#include "Space.h"

#include <SDL2\SDL_opengl.h>
#include <iostream>

#define MAX_JUMP_HEIGHT 0.2f
#define SPAWN_X -0.42f

void Player::init(Space * s){ //INITIALIZING SPACE CLASS OBJECT
    space = s;
    spritePiece = 0.125f;
}

void Player::drawPlayer(){
    glPushMatrix();
        glEnable(GL_TEXTURE_2D);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glBindTexture(GL_TEXTURE_2D, space->getWindow().getTexture(1));
            glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
                glBegin(GL_QUADS);
                    //PART OF THE SPRITESHEET                     DRAWING COORDINATES
                    glTexCoord2f(spritePart, 0.0f);               if (strafeRight) { glVertex2f(playerX        , playerY + 0.52f); } else { glVertex2f(playerX        , playerY + 0.52f); }
                    glTexCoord2f(spritePart + spritePiece, 0.0f); if (strafeRight) { glVertex2f(playerX + 0.13f, playerY + 0.52f); } else { glVertex2f(playerX - 0.13f, playerY + 0.52f); }
                    glTexCoord2f(spritePart + spritePiece, 1.0f); if (strafeRight) { glVertex2f(playerX + 0.13f, playerY)        ; } else { glVertex2f(playerX - 0.13f, playerY        ); }
                    glTexCoord2f(spritePart, 1.0f);               if (strafeRight) { glVertex2f(playerX        , playerY)        ; } else { glVertex2f(playerX        , playerY        ); }
                glEnd();
            glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_2D);
    glPopMatrix();
}

void Player::move(){
    chanceToMove++;
    if (!attacking){ //NORMAL WALK ANIMATION
        if (playerXSpeed != 0.0f) {
            if (spriteCount != sprites - 3) { //IF CURRENT PART IS NOT THE LAST PART
                if (chanceToMove % 4 == 0) { //SO THE ANIMATION IS NOT AS FAST AS SANIC IS
                    spritePart += spritePiece;
                    spriteCount++;
                }
            }else {
                spritePart = 0.0f;
                spriteCount = 0;
            }
        }else {
            spritePart = 0.0f; //ALSO RESET
        }
    }else { //ATTACKING
        spritePart = spritePiece * (sprites - 2); //ATTACK SPRITE
        projectileAttack();
        if (times == 5) {
            attacking = false;
            times = 0;
        }else {
            times++;
        }
    }

    if (playerXSpeed < 0) { //IF PLAYER IS MOVING LEFT
        strafeRight = false;
    }else {
        strafeRight = true; //MOVING RIGHT
    }

    if (jumping) {
        jump();
    }

    playerX += playerXSpeed; //UPDATING PLAYER POSITIONS
    playerY += playerYSpeed;
}

void Player::checkFalling() {
    if ((playerX < space->getGame().getPlatformLeft() - 0.1f || playerX > space->getGame().getPlatformRight() - 0.05f) && playerY < -0.4f) { //IF PLAYER JUMPED OFF THE PLATFORM
        ableToChangeY = false;
        playerYSpeed = -0.03f;
    }if (playerY < -2.0f) { //IF PLAYER FELL TO DEATH(RIP)
        space->getGame().stopGame();
    }
}

void Player::setJumping(bool value){
    jumping = value;
}

void Player::setAttacking(bool value){
    attacking = value;
}

void Player::projectileAttack(){

}

void Player::jump(){
    spritePart = spritePiece * (sprites-1); //JUMPING SPRITE
    if (ableToChangeY) { //IF PLAYER IS NOT FALLING RIP
        if (playerY < MAX_JUMP_HEIGHT && !falling) { //WHILE THE PLAYER DID NOT PASS THE MAXIMUM JUMP HEIGHT
            playerYSpeed = 0.03f;
        }else { //IF THE PLAYER JUMPED TOO HIGH
            falling = true;
            if (playerY > SPAWN_X) {
                playerYSpeed = -0.03f;
            }else { //PLAYER IS BACK ON EARTH
                jumping = false;
                falling = false;
                playerYSpeed = 0.0f;
            }
        }
    }
}

void Player::setPlayerXSpeed(float speed){
    playerXSpeed = speed;
}

float Player::getPlayerX()
{
    return playerX;
}

float Player::getPlayerY(){
    return playerY;
}
#包括“Player.h”
#包括“Space.h”
#包括
#包括
#定义最大跳跃高度0.2f
#定义SPAWN_X-0.42f
void Player::init(Space*s){//初始化空间类对象
空间=s;
spritePiece=0.125f;
}
void Player::drawPlayer(){
glPushMatrix();
glEnable(GL_纹理_2D);
glEnable(GL_混合物);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_减去GL_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D,space->getWindow().getTexture(1));
glColor4f(1.0f、1.0f、1.0f、1.0f);
glBegin(GL_QUADS);
//精灵表图形坐标的一部分
glTexCoord2f(spritePart,0.0f);if(strafeRight){glVertex2f(playerX,playerY+0.52f);}else{glVertex2f(playerX,playerY+0.52f);}
glTexCoord2f(spritePart+spritepice,0.0f);if(strafeRight){glVertex2f(playerX+0.13f,playerY+0.52f);}否则{glVertex2f(playerX-0.13f,playerY+0.52f);}
glTexCoord2f(spritePart+spritepice,1.0f);if(strafeRight){glVertex2f(playerX+0.13f,playerY);}else{glVertex2f(playerX-0.13f,playerY);}
glTexCoord2f(spritePart,1.0f);if(strafeRight){glVertex2f(playerX,playerY);}else{glVertex2f(playerX,playerY);}
格伦德();
glDisable(GLU混合);
glDisable(GL_纹理_2D);
glPopMatrix();
}
void Player::move(){
chanceToMove++;
如果(!攻击){//正常行走动画
如果(播放速度!=0.0f){
if(spriteCount!=sprites-3){//如果当前部分不是最后一部分
如果(chanceToMove%4==0){//,则动画速度不如SANIC快
spritePart+=spritePiece;
spriteCount++;
}
}否则{
spritePart=0.0f;
spriteCount=0;
}
}否则{
spritePart=0.0f;//也重置
}
}否则{//
精灵艺术=精灵画*(精灵-2);//攻击精灵
投射攻击();
如果(次数==5){
攻击=错误;
次数=0;
}否则{
时代++;
}
}
如果(playerXSpeed<0){//如果玩家向左移动
Straferlight=假;
}否则{
Straferlight=true;//向右移动
}
如果(跳跃){
跳跃();
}
playerX+=playerXSpeed;//更新玩家位置
playerY+=playerYSpeed;
}
void Player::checkFalling(){
如果((playerXgetGame().getPlatformLeft()-0.1f | | playerX>space->getGame().getPlatformRight()-0.05f)&&playerY<-0.4f){//
能够改变=错误;
PlayerSpeed=-0.03f;
}如果(游戏性<-2.0f){//如果玩家倒地死亡(RIP)
space->getGame().stopGame();
}
}
无效玩家::设置跳跃(布尔值){
跳跃=价值;
}
无效玩家::设置攻击(布尔值){
攻击=价值;
}
void Player::projectLeattack(){
}
void Player::jump(){
精灵艺术=精灵画*(精灵-1);//跳跃精灵
如果(能够改变){//如果玩家没有摔倒
如果(playerY繁殖){
PlayerSpeed=-0.03f;
}否则{//玩家将返回地球
跳跃=错误;
下降=错误;
PlayerSpeed=0.0f;
}
}
}
}
void Player::setPlayerXSpeed(浮动速度){
playerXSpeed=速度;
}
浮点播放器::getPlayerX()
{
返回playerX;
}
float Player::getPlayerY(){
回归游戏;
}
编辑主功能

#include "Space.h"
#include <iostream>
#include <SDL2\SDL.h>
#include <SDL2\SDL_opengl.h>
#include <SDL2\SDL_ttf.h>
#undef main

int main(int argc, char** argv) {
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    TTF_Init();

    Space space;
    space.init();

    std::cout << "Type something and press ENTER to quit..." << std::endl;
    char temp;
    std::cin >> temp;

    TTF_Quit();
    SDL_Quit();
    return 0;
}
#包括“Space.h”
#包括
#包括
#包括
#包括
#未定义主
int main(int argc,字符**argv){
SDL_Init(SDL_Init_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
TTF_Init();
空间;
space.init();
标准:冷却温度;
TTF_Quit();
SDL_退出();
返回0;
}

如果您发布一个更完整的问题编译示例,您可能会更幸运。base上的
drawPlayer()
方法是否依赖于指针
空格
有效?如果是这样,您需要首先初始化它。您可以在基类中将
space
声明为protected,然后在派生的
init
方法中将传入的
s
指针分配给它。对于要访问的有效内存地址,0x00000028也是一个非常低的数字,我希望您会收到此错误,因为space*space尚未初始化(正确),但如果没有更多信息,很难判断。在你的敌人.cpp文件中,你不需要包含Player.h。你已经包含了敌人.h,它已经包含了
#pragma once

class Space;
class Player {
public:
    void init(Space * s);
    void drawPlayer();
    void setPlayerXSpeed(float speed);
    void move();
    void jump();
    void checkFalling();
    void setJumping(bool value);
    void setAttacking(bool value);
    void projectileAttack();

    float getPlayerX();
    float getPlayerY();

private:
    Space * space;

    int sprites = 8;
    int chanceToMove = 0;
    int times = 0;
    int spriteCount = 0;

    float spritePart = 0.0f;
    float spritePiece;
    float playerX = -0.7f;
    float playerY = -0.42f;
    float playerXSpeed = 0.0f;
    float playerYSpeed = 0.0f;

    bool ableToChangeY = true;
    bool jumping = false;
    bool falling = false;
    bool strafeRight = true;
    bool attacking = false;
};
#include "Player.h"
#include "Space.h"

#include <SDL2\SDL_opengl.h>
#include <iostream>

#define MAX_JUMP_HEIGHT 0.2f
#define SPAWN_X -0.42f

void Player::init(Space * s){ //INITIALIZING SPACE CLASS OBJECT
    space = s;
    spritePiece = 0.125f;
}

void Player::drawPlayer(){
    glPushMatrix();
        glEnable(GL_TEXTURE_2D);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glBindTexture(GL_TEXTURE_2D, space->getWindow().getTexture(1));
            glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
                glBegin(GL_QUADS);
                    //PART OF THE SPRITESHEET                     DRAWING COORDINATES
                    glTexCoord2f(spritePart, 0.0f);               if (strafeRight) { glVertex2f(playerX        , playerY + 0.52f); } else { glVertex2f(playerX        , playerY + 0.52f); }
                    glTexCoord2f(spritePart + spritePiece, 0.0f); if (strafeRight) { glVertex2f(playerX + 0.13f, playerY + 0.52f); } else { glVertex2f(playerX - 0.13f, playerY + 0.52f); }
                    glTexCoord2f(spritePart + spritePiece, 1.0f); if (strafeRight) { glVertex2f(playerX + 0.13f, playerY)        ; } else { glVertex2f(playerX - 0.13f, playerY        ); }
                    glTexCoord2f(spritePart, 1.0f);               if (strafeRight) { glVertex2f(playerX        , playerY)        ; } else { glVertex2f(playerX        , playerY        ); }
                glEnd();
            glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_2D);
    glPopMatrix();
}

void Player::move(){
    chanceToMove++;
    if (!attacking){ //NORMAL WALK ANIMATION
        if (playerXSpeed != 0.0f) {
            if (spriteCount != sprites - 3) { //IF CURRENT PART IS NOT THE LAST PART
                if (chanceToMove % 4 == 0) { //SO THE ANIMATION IS NOT AS FAST AS SANIC IS
                    spritePart += spritePiece;
                    spriteCount++;
                }
            }else {
                spritePart = 0.0f;
                spriteCount = 0;
            }
        }else {
            spritePart = 0.0f; //ALSO RESET
        }
    }else { //ATTACKING
        spritePart = spritePiece * (sprites - 2); //ATTACK SPRITE
        projectileAttack();
        if (times == 5) {
            attacking = false;
            times = 0;
        }else {
            times++;
        }
    }

    if (playerXSpeed < 0) { //IF PLAYER IS MOVING LEFT
        strafeRight = false;
    }else {
        strafeRight = true; //MOVING RIGHT
    }

    if (jumping) {
        jump();
    }

    playerX += playerXSpeed; //UPDATING PLAYER POSITIONS
    playerY += playerYSpeed;
}

void Player::checkFalling() {
    if ((playerX < space->getGame().getPlatformLeft() - 0.1f || playerX > space->getGame().getPlatformRight() - 0.05f) && playerY < -0.4f) { //IF PLAYER JUMPED OFF THE PLATFORM
        ableToChangeY = false;
        playerYSpeed = -0.03f;
    }if (playerY < -2.0f) { //IF PLAYER FELL TO DEATH(RIP)
        space->getGame().stopGame();
    }
}

void Player::setJumping(bool value){
    jumping = value;
}

void Player::setAttacking(bool value){
    attacking = value;
}

void Player::projectileAttack(){

}

void Player::jump(){
    spritePart = spritePiece * (sprites-1); //JUMPING SPRITE
    if (ableToChangeY) { //IF PLAYER IS NOT FALLING RIP
        if (playerY < MAX_JUMP_HEIGHT && !falling) { //WHILE THE PLAYER DID NOT PASS THE MAXIMUM JUMP HEIGHT
            playerYSpeed = 0.03f;
        }else { //IF THE PLAYER JUMPED TOO HIGH
            falling = true;
            if (playerY > SPAWN_X) {
                playerYSpeed = -0.03f;
            }else { //PLAYER IS BACK ON EARTH
                jumping = false;
                falling = false;
                playerYSpeed = 0.0f;
            }
        }
    }
}

void Player::setPlayerXSpeed(float speed){
    playerXSpeed = speed;
}

float Player::getPlayerX()
{
    return playerX;
}

float Player::getPlayerY(){
    return playerY;
}
#include "Space.h"
#include <iostream>
#include <SDL2\SDL.h>
#include <SDL2\SDL_opengl.h>
#include <SDL2\SDL_ttf.h>
#undef main

int main(int argc, char** argv) {
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    TTF_Init();

    Space space;
    space.init();

    std::cout << "Type something and press ENTER to quit..." << std::endl;
    char temp;
    std::cin >> temp;

    TTF_Quit();
    SDL_Quit();
    return 0;
}