【发布时间】:2016-08-17 14:10:48
【问题描述】:
我使用早期版本的 Cocos2dx 编写游戏并使用 VS 2013 对其进行编译。请注意,我将 CMake 和 Qt Creator 与两个编译器版本一起使用。当 Cocos2dx v3.12 出来时,我决定在我的游戏中将 lib 升级到那个版本并开始使用 VS 2015。然后我开始收到这个错误:
QCardManager.cpp.obj:-1:错误:LNK2001:未解析的外部符号 “公共:静态类 QCard * __cdecl QCard::create(enum PLAYER,struct 问题 const *,enum CARD_TYPE,int const &)" (?create@QCard@@SAPAV1@W4PLAYER@@PBUQuestion@@W4CARD_TYPE@@ABH@Z)
我在使用 VS 2013 时并没有遇到这个错误。经过几个小时的调试,我找到了原因。
这是QCard的粗略声明:
#include "2d/CCSprite.h"
#include "CommonVariables.h"
class RandomPostureSprite;
class Question;
namespace cocos2d
{
class Label;
}
enum class CARD_TYPE {
QUESTION,
OPTION
};
class QCard : public cocos2d::Sprite
{
public:
static QCard *create(PLAYER player, const Question *question, CARD_TYPE type, const int &index);
}
我在QCard.cpp 文件中正确实现了该功能,并且该文件也已正确添加到项目中。
所以问题是class Question; 前向声明。我在QCard.cpp 中包含了QuestionParser.h 文件,但由于我在QCard.h 中使用了QCard 的前向声明,QCardManager.cpp 文件没有Question 的实现,因此链接器错误。
这是我的问题:我意识到 VS 2015 所做的应该是预期的行为。但为什么会发生这种行为?相同的代码在 VS 2013 上编译没有错误,但在 VS 2015 上没有。我阅读了Breaking Changes in Visual C++ 2015 指南,但看不到任何相关内容。
编辑 1:
结果证明前向声明应该是struct Question 而不是class Question。当我尝试在QCardManager.cpp 中使用QCard::create 时,出现上述链接器错误。但不在同一目录中的TimerHUD.cpp 中。我将发布它们的摘要内容。请记住,我将 QCard 的声明与此编辑保持一致。
问题结构,位于QuestionParser.h:
struct Question {
Question()
: type()
, source()
, alias()
, color(0, 0, 0)
{}
};
QCardManager.h
// Cocos2dx
#include "math/Vec2.h"
#include "math/CCGeometry.h"
// Utilities
#include "CommonVariables.h"
// Local
#include "GameDefinitions.h"
#include "QuestionParser.h"// This has the Question struct
// Forward declerations
class QCard;
namespace cocos2d
{
class Layer;
class Sprite;
}
class QCardManager
{
}
QCardManager.cpp
#include "QCardManager.h"
// Local
#include "QCard.h"
#include "RandomPostureSprite.h"
// Utilities
#include "GameManager.h"
#include "GameSettings.h"
#include "CocosUtils.h"
// Cocos2dx
#include "cocos2d.h"
using namespace cocos2d;
QCardManager::QCardManager(PLAYER player, Layer &parent)
{
// This line gives the linker error
QCard::create(PLAYER::PLAYER_ONE, nullptr, CARD_TYPE::QUESTION, 1);
}
QCardManager 引发链接器错误。但是TimerHUD 没有。我现在正在分享内容。
TimerHUD.h
// Cocos2dx
#include "2d/CCNode.h"
namespace cocos2d
{
class Sprite;
class Label;
}
class TimerHUD : public cocos2d::Node
{
}
TimerHUD.cpp
// Cocos2dx
#include "cocos2d.h"
#include "SimpleAudioEngine.h"
// Local
#include "GameDefinitions.h"
// Utilities
#include "GameManager.h"
#include "GameSettings.h"
#include "CocosUtils.h"
#include "QCard.h"
using namespace cocos2d;
TimerHUD::TimerHUD()
{
// This does not raise the linker error
QCard::create(PLAYER::PLAYER_ONE, nullptr, CARD_TYPE::QUESTION, 1);
}
【问题讨论】:
-
你说得对,
Question是struct。将前向声明从class Question;更改为struct Question后,问题就消失了。但这对我提出了另一个问题,在进行更改之前,引发错误的相同代码并未在另一个类中引发错误。我在问题的编辑中添加了更多解释。谢谢。
标签: c++ visual-c++