如果没有发布大量代码,我会解释这个问题有点复杂,但我会尽我所能。我正在编写一个游戏内控制台,它要求我将正常的自由函数和实例方法绑定到控制台,以便可以使用简单的关键字调用它们。控制台可以绑定的每个方法/函数都需要一个sf :: String参数,并返回一个sf :: String。 (我在游戏中使用SFML,而sf是SFML的命名空间)
[注意:所有4个类(Console,CFunctionInterface,CFunction和CMethod)都在同一个文件(console.h)中声明。他们的成员都在一个文件(console.cpp)中定义。
要设置它,我有1个父(CFunctionInterface)和2个子(CFunction,CMethod)'容器'类。父母在其中有一个公共方法。
sf::String call(sf::String p_Value);
CFunction的声明如下:
class CFunction : public CFunctionInterface
{
public:
typedef sf::String (*FFP)(sf::String); //free function pointer type
CFunction(const FFP p_Function);
sf::String call(const sf::String p_Value);
private:
FFP m_Function;
};
CMethod的声明如下:
template <typename ClassType>
class CMethod : public CFunctionInterface
{
public:
typedef sf::String (ClassType::*MFP)(sf::String); //member function pointer type
CMethod(const ClassType* p_Instance, const MFP p_Function);
sf::String call(const sf::String p_Value);
private:
ClassType* m_Instance;
MFP m_Function;
};
一切都是非常自我解释的,我相信你可以想象call()对每个类的作用。
回到控制台,我有一个
std::multimap <string, CFunctionInterface* >
设置存储所有函数指针。当我想调用一个函数时,将迭代此映射,如果输入函数名称与其中一个键匹配,则将调用该键的值。例如(name是所需函数的所需键,param是我要传递给函数的sf :: String [push_back()是一个向控制台输出消息的控制台方法]):
for(auto iter = functions.begin(); iter!= functions.end(); iter++)
{
if(iter->first == name)
{
push_back(iter->second->call(param));
return;
}
}
push_back("Error! Function with name: " + name + " not found!");
现在我在控制台内部有一些方法,用于绑定和取消绑定函数。这就是出现问题的地方。
template <typename ClassType>
void bindFunction(const string name, const ClassType* instance, sf::String (ClassType::*func)(sf::String));
void bindFunction(const string name, sf::String (*func)(sf::String));
void unbindFunction(const string name);
最后两个功能很漂亮。没有问题。但这是模板混蛋。 这是他的定义(在console.cpp中):
template <typename ClassType>
void CConsole::bindFunction(const string name, const ClassType* instance, sf::String (ClassType::*func)(sf::String))
{
//Checks to see if name is already in use
for(auto iter = functions.begin(); iter != functions.end(); iter++)
{
if(iter->first == name)
{
push_back("Error! Attempting to bind function. The name \'" + name + "\' is already in use!");
return;
}
}
//Everything checks out
CMethod* temp = new CMethod<ClassType> (instance, func);
functions.insert( pair<string, CFunctionInterface* > (name, temp) );
}
当我在整个程序中根本不打电话给他时,它编译并运行得很好。但是当我试着打电话的时候;我收到这个错误:
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall CConsole::bindFunction<class CDog>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class CDog const *,class sf::String (__thiscall CDog::*)(class sf::String))" (??$bindFunction@VCDog@@@CConsole@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PBVCDog@@P83@AE?AVString@sf@@V45@@Z@Z) referenced in function _main
1>S:\Users\Logan\documents\visual studio 2012\Projects\newConsole\Debug\newConsole.exe : fatal error LNK1120: 1 unresolved externals
这就是在'int main()'中调用它的方式:
CDog* rex = new CDog;
console->bindFunction<CDog>("bark", rex, &CDog::bark);
CDog只是一个带有公共bark()方法的简单类,返回“Woof!”。 控制台正在main中创建,并且只是指向新CConsole对象的指针。 包含“console.h”,并且没有#include循环。我查过了。
我在线做了一些googleing,但我从来没有发现像这样的链接器错误。它总是忘记包含或包含循环。
有谁知道我做错了什么,以及如何解决?感谢您抽出宝贵时间阅读本文,并提前感谢您的回复。 - 洛根