我有这个错误:
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;
}
我需要一个指向空间对象的指针,因为我的基类也需要它。我不确定是否需要这样做。
这就是我调用base(Player)类的函数的方法:
space->getEnemy().drawPlayer(); //FIRST I GET THE OBJECT OF THE DERIVED(ENEMY CLASS) AND THAN I CALL A FUNCTION FROM THE BASE CLASS(PLAYER CLASSS)
错误消息“无法读取内存”发生在基类需要的类中的getter函数中(例如指向窗口的指针)。
有谁知道我做错了什么?
修改
我忘了告诉:我在项目的每个类中初始化了指向我的导入类Space的空间指针。如果我不调用Enemy类的继承内容,那么该程序可以正常使用这些空格指针
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();
};
Space.cpp:
#include "Space.h"
//PASSING THE SPACE CLASS OBJECT TO THE INIT FUNCTIONS OF THE OTHER CLASSES
void Space::init(){
windowObj.init(this);
gameObj.init(this);
inputObj.init(this);
textObj.init(this);
playerObj.init(this);
enemyObj.init(this);
//STARTING THE GAME ACTUALLY
windowObj.createWindow();
}
Enemy & Space::getEnemy() {
return enemyObj;
}
Window & Space::getWindow(){
return windowObj;
}
Game & Space::getGame() {
return gameObj;
}
Input & Space::getInput() {
return inputObj;
}
Text & Space::getText() {
return textObj;
}
Player & Space::getPlayer(){
return playerObj;
}
int Space::getStartTime(){
return startTime;
}
Player.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;
};
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;
}
编辑主要功能
#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;
}