gpt4 book ai didi

c++ - 前向声明的循环包含和继承导致 C2504 基类未定义

转载 作者:行者123 更新时间:2023-11-28 01:46:06 27 4
gpt4 key购买 nike

我在 PlayerController.h 中收到 C2504 编译错误,指出我的基类 (Updateable) 未定义。我已经搜索了几个小时来寻找解决循环包含继承问题的方法,他们的解决方案是删除循环包含并且只使用前向声明。据我了解,如果没有调用前向声明类中的方法,则此方法有效。但是,在我的程序中,我的 Updateables 类在其成员继承的 gameObject 对象上调用一个方法,而 GameObjects 也在其成员 Updateables 上调用方法。因此,Updateables 需要包含 GameObject.h,而 GameObjects 需要包含 Updateables.h。这导致 PlayerController.h 中的 C2504 指出找不到基类 Updateable。

这是我的相关类(class):

组件.h

#pragma once
#include "Vector3.h"

class GameObject;

class Component {
public:
GameObject* gameObject = nullptr;

Component();
};

组件.cpp

#include "Component.h"

Component::Component() {}

可更新的.h

#pragma once

#include "Component.h"
#include "GameObject.h"

class GameObject;

class Updateable : public Component {

public:
~Updateable();
virtual void update() = 0;
};

可更新.cpp

#include "Updateable.h"

Updateable::~Updateable() {

if (gameObject) {
gameObject->removeUpdateable(this);
}
}

游戏对象.h

#pragma once

#include "Updateable.h"
#include "GameManager.h"

class Updateable;

class GameObject {

public:

GameObject();
~GameObject();

void runUpdateables();
void addUpdateable(Updateable* updateable);
void removeUpdateable(Updateable* updateable);

private:
vector<Updateable*> updateables;
};

游戏对象.cpp

#include "GameObject.h"

GameObject::GameObject() {

updateables = vector<Updateable*>();
GameManager::addGameObject(this);
}

GameObject::~GameObject() {

GameManager::removeGameObject(this);
}

void GameObject::runUpdateables() {

for (unsigned int i = 0; i < updateables.size(); i++) {
updateables[i]->update();
}
}

void GameObject::addUpdateable(Updateable* updateable) {

updateables.push_back(updateable);
updateable->gameObject = this;
}

void GameObject::removeUpdateable(Updateable* updateable) {

auto it = find(updateables.begin(), updateables.end(), updateable);
if (it != updateables.end()) {
updateables.erase(it);
}
}

PlayerController.h

#pragma once

#include "Updateable.h"
//#include "GameObject.h"
#include "Input.h"

class Updateable;

class PlayerController : public Updateable {

public:

float speed = 5.0f;

void update();
};

播放器 Controller .cpp

#include "PlayerController.h"

void PlayerController::update() {

float x = 0;

if (Input::getKeyDown(GLFW_KEY_A)) {
x = -speed;
}

if (Input::getKeyDown(GLFW_KEY_D)) {
x = speed;
}

cout << x << endl;

gameObject->getRigidBody()->velocity.x = x;
//yes this is a method in GameObject that I removed from this post
//because it would take up more space, rigidbody.h does not create
//a circular dependency
}

游戏管理器.h

#pragma once

#include "GameObject.h"
#include "PlayerController.h"

class GameManager {

public:

static void init();
static void addGameObject(GameObject* go);
static void removeGameObject(GameObject* go);

static void onFrame();

private:
static vector<GameObject*> gameObjects;
static GameObject* box;

游戏管理器.cpp

#include "GameManager.h"

vector<GameObject*> GameManager::gameObjects;
GameObject* GameManager::box;

void GameManager::init() {

gameObjects = vector<GameObject*>();

box = new GameObject();
box->addUpdateable(new PlayerController());
}

void GameManager::addGameObject(GameObject* go) {
gameObjects.push_back(go);
}

void GameManager::removeGameObject(GameObject* go) {

auto it = find(gameObjects.begin(), gameObjects.end(), go);
if (it != gameObjects.end()) {
gameObjects.erase(it);
}
}

void GameManager::onFrame() {

for (unsigned int i = 0; i < gameObjects.size(); i++) {
gameObjects[i]->runUpdateables();
}
}

这是确切的错误消息:Error C2504 'Updateable': base class undefined Basic Platformer c:\users\default.sixcore-pc\documents\visual studio 2015\projects\basic platformer\basic platformer\playercontroller.h 9

最佳答案

您的许多文件都有 #include "Class.h"class Class; 声明。你永远不需要两者;使用其中之一。

X 的定义在以下情况下必须可见:

  • 访问X的成员
  • 创建 X 类型的对象>
  • 定义从 X 派生的类
  • 使用 X 作为模板的模板参数,该模板要求相应的模板参数是完整类型(例如标准库容器对其元素类型的要求)。请注意,这适用于使用 X 而不是 X* 的情况。

在其他情况下(例如创建指向X 的指针或声明一个接受返回X 的函数),非定义声明(class X; ) 就足够了。

使用这些规则(加上必要时将函数体从头文件移动到源文件),您可以解决任何循环依赖问题。


如直接显示您的文件地址:

  • Updateable.h 不需要#include "GameObject.h"。它甚至不需要 GameObject 的前向声明。
  • GameObject.h 不需要其中的任何两个 #include
  • GameManager.h 不需要任何 #include。不过,它需要声明 class GameObject;

关于c++ - 前向声明的循环包含和继承导致 C2504 基类未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45029036/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com