我最近在使用虚方法/继承的C ++中遇到了一些麻烦
首先,如果我尝试扩展超类,我会收到此错误:
'对GameState :: GameState()'
的未定义引用
但是如果我一起删除构造函数我没有得到上述错误,但我最终得到了调用虚方法时出现的分段错误。
这是我的代码:
#ifndef GAMESTATE_H
#define GAMESTATE_H
#include <stdlib.h>
#include "Resources.h"
#include "Renderer.h"
class GameState {
public:
GameState();
virtual void init(Resources *res) = 0;
virtual void exit() = 0;
virtual void update() = 0;
virtual void render(Renderer *renderer) = 0;
};
#endif // GAMESTATE_H
这是子类:
#include "GameState.h"
class MainGameState : public GameState {
public:
MainGameState() : GameState() {
}
virtual void init(Resources *res) {
}
virtual void update() {
printf("test\n");
}
virtual void render(Renderer *renderer) {
}
virtual void exit() {
}
private:
SDL_Surface *image;
};
答案 0 :(得分:2)
尝试
GameState() { }
而不是
GameState();
或将其定义在其他地方。
虽然,我不确定它是否与虚拟方法有关。我认为其他地方有一个错误。也许,未初始化的指针?
答案 1 :(得分:1)
如果要显式调用它,则需要为构造函数提供实现:
class GameState {
public:
GameState() {} // implementation
virtual void init(Resources *res) = 0;
virtual void exit() = 0;
virtual void update() = 0;
virtual void render(Renderer *renderer) = 0;
};
答案 2 :(得分:1)
这是一个完整的程序,它实现了您正在寻找的基类和派生类。您收到链接器错误消息,因为您从未实现过GameState::GameState
。目前尚不清楚为什么会出现分段错误。
还要记住,如果要以多态方式删除对象,请声明并定义虚拟基类析构函数。
#include <iostream>
#define X() (std::cout << __FUNCTION__ << "\n")
class GameState {
public:
GameState() { X(); }
virtual ~GameState() { X(); }
virtual void F() = 0;
};
class MainGameState : public GameState {
public:
MainGameState() : GameState() { X(); }
void F() { X(); }
~MainGameState() { X(); }
};
int main () {
GameState* pGS = new MainGameState;
X();
pGS->F();
delete pGS;
}
答案 3 :(得分:0)
无论如何,编译器将为您调用无参数基类构造函数(默认构造函数),因此不需要。但是,您是否为GameState::GameState()
提供了定义?可能不是,所以你应该摆脱它或提供一个实现(即GameState() { }
)。
我们需要看看你是如何调用这个函数的。这对我来说很好,你的错误在其他地方。您是否可能声明指向对象的指针,而不是初始化它,然后调用update()
?
如果我必须猜测(显然我确实......)我敢打赌你有这样的事情:
MainGameState *state;
state->update(); // oops! Not initialize!
当然我可能错了,但就像我说的那样,我被迫猜测,直到你用真实的代码更新你的问题。
答案 4 :(得分:0)
此错误'Undefined reference to GameState::GameState()'
告诉您未定义GameState构造函数。它与虚方法无关。
做@Luchian和@Micheal说的话:
class GameState {
public:
GameState() {} // implementation
如果是虚拟方法错误,您会得到类似"the 'MainGameState' must implement inherited pure virtual method 'method name'"
编辑:请注意,在实例化子类时会隐式调用超类构造函数。