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

Posted

技术标签:

【中文标题】C++ 未定义的抽象类构造函数【英文标题】:C++ Undefined abstract class constructor 【发布时间】:2012-02-23 22:02:31 【问题描述】:

我最近在使用虚拟方法/继承的 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;
;

【问题讨论】:

你在哪里定义GameState::GameState 你是如何使用这些类的 也许发布一个示例调用。您也可以尝试询问 valgrind 是什么导致了分段错误 你的第一个错误是因为抽象类GameState没有给它的构造函数定义,但是MainGameState构造函数调用了它。只需将 GameState(); 更改为 GameState() 即可解决此问题。如果您在段错误之前告诉我们您正在调用哪个虚拟方法,我们可以在第二个方面提供更多帮助。 【参考方案1】:

试试

GameState()  

而不是

GameState();

或在其他地方定义它。

不过,我不确定它是否与虚拟方法有关。我认为其他地方存在错误。也许,未初始化的指针?

【讨论】:

【参考方案2】:

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

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

【讨论】:

我认为您不应该在此处放置分号。【参考方案3】:

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

【讨论】:

【参考方案4】:

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

按照@Luchian 和@Micheal 所说的去做:

class GameState 
public:
    GameState()  // implementation

如果是虚方法错误,你会得到类似"the 'MainGameState' must implement inherited pure virtual method 'method name'"

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

【讨论】:

【参考方案5】:

    编译器无论如何都会为你调用一个无参数的基类构造函数(默认构造函数),所以没有必要。但是,您是否甚至提供了GameState::GameState() 的定义?可能不是,所以你应该摆脱它或提供一个实现(即GameState() )。

    我们需要看看你是如何调用函数的。这对我来说看起来不错,你的错误在其他地方。您是否可能声明了一个指向对象的指针,而不是对其进行初始化,然后调用update()

如果我必须猜测(显然我会......)我敢打赌你有这样的事情:

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

当然我可能是错的,但就像我说的,我不得不猜测,直到你用真实代码更新你的问题。

【讨论】:

@LuchianGrigore:哈哈,是的,我知道,那是精神上的昙花一现。我经常在 C# 和 C++ 之间来回切换,以至于我有时会混淆两者之间的语法。在您发表评论之前,我已将其编辑掉。谢谢。 此外,该术语是“默认构造函数”。你可能已经知道了,我猜你使用了无参数,所以操作更容易理解。 @LuchianGrigore:是的,我知道,默认构造函数是无参数的。 :) 我想通了。在写完整个评论之前,我只是按了 Enter 键 :) @LuchianGrigore:是的,不过你是对的;与相对的初学者交谈时使用共同语言并没有什么坏处,以免他们将来感到困惑。我只是希望我能看到他是如何调用出错的函数......

以上是关于C++ 未定义的抽象类构造函数的主要内容,如果未能解决你的问题,请参考以下文章

接受对抽象类的 const 引用的 C++ 构造函数无法初始化 std::map

C++ 抽象类:构造函数是或否?

C++:对象和类|| 类的构造函数与析构函数

C++:对象和类|| 类的构造函数与析构函数

无法实例化抽象类我认为我搞砸了我的构造函数 C++

c++ 接口必须遵守五法则吗?