C++未定义的抽象类构造函数

C++ Undefined abstract class constructor

本文关键字:构造函数 抽象类 未定义 C++      更新时间:2023-10-16

我最近在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("testn");
    }
    virtual void render(Renderer *renderer) {
    }
    virtual void exit() {
    }
private:
    SDL_Surface *image;
};

尝试

GameState() { }

而不是

GameState();

或者在其他地方定义它。

不过,我不确定它是否与虚拟方法有关。我想其他地方有个bug。也许,未初始化的指针?

如果要显式调用构造函数,则需要为其提供一个实现:

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;
};

这里有一个完整的程序,它实现了您要查找的基类和派生类。您收到链接器错误消息,因为您从未实现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;
}

此错误'Undefined reference to GameState::GameState()'告诉您GameState构造函数未定义。它与虚拟方法无关。

照@Luchian和@Micheal说的做:

class GameState {
public:
    GameState() {} // implementation

如果这是一个虚拟方法错误,你会得到类似"the 'MainGameState' must implement inherited pure virtual method 'method name'" 的东西

EDIT:请注意,当实例化子类时,会隐式调用超类构造函数。

  1. 编译器无论如何都会为您调用一个无参数基类构造函数(默认构造函数),所以这是不必要的。但是,您是否提供了GameState::GameState()的定义?可能不会,所以您应该去掉它或提供一个实现(即GameState() { })。

  2. 我们需要看看你是如何调用函数的。我觉得不错,你的虫子在别的地方。您是否声明了一个指向对象的指针,而不是初始化它,然后调用update()

如果非要我猜(显然我猜…),我敢打赌你有这样的东西:

MainGameState *state;
state->update();  // oops!  Not initialize!

当然,我可能错了,但正如我所说,我不得不猜测,直到你用真实的代码更新你的问题。