提问人:Reciever80 提问时间:3/13/2013 更新时间:3/13/2013 访问量:227
链接器 2001 成员变量的错误和未定义的标识符
Linker 2001 Error and undefined identifier for member variable
问:
差不多完成了这个程序,在移动到公共计算机并更改了一些代码后,我注意到我收到了一个链接器错误,我还决定询问另一个错误(以及为什么会发生)。
有问题的函数如下。出于某种原因,最后一行“ValidTlds[transferString]....”显示 VS 无法识别 ValidTLD,并且只有在我在其后面添加 TldPart::(它所在的文件的名称)时才会识别。这个名字是否与其他名称冲突?
此外,我认为更重要的错误也涉及函数,是未解析的外部符号。确切的线路:
Error 3 error LNK2001: unresolved external symbol "public: static class std::map<class String,class String,struct std::less<class String>,class std::allocator<struct std::pair<class String const ,class String> > > TldPart::ValidTlds" (?ValidTlds@TldPart@@2V?$map@VString@@V1@U?$less@VString@@@std@@V?$allocator@U?$pair@$$CBVString@@V1@@std@@@3@@std@@A) V:\My Documents\Visual Studio 2010\Projects\EmailChecker_HW2\EmailChecker_HW2\TldPart.obj
我试着阅读了你关于外部符号的问答页面,并尝试了一些建议(最初我有两个),我设法通过在类外声明静态函数来减少它,我相信这是一个链接器错误。你们看到怎么了?在主要.cpp中,我将该函数引用为“TldPart::P reloadTLDs;”,但删除该行并没有删除错误(我在主.cpp文件的顶部 #include“TldPart.h”)。这是函数,我将在下面发布标题和 cpp 文件以供完整参考。整个项目非常广泛(我上次检查了近 1100 行),所以我只包括这些作为初学者。感谢您的帮助,我很感激。
static void 预加载TLDs()
static void PreloadTLDs()
{
bool initialized = false;
bool fileStatus = false;
string tldTest = ""; // used for getline() as allowed.
char * transferString = " "; // used to transfer chars from string to String
ifstream infile;
infile.open("ValidTLDs.txt");
fileStatus = infile.good();
if(fileStatus != true)
cout << "Cannot read ValidTLD's file. Please check your file paths and try again.";
else
{
while(!infile.eof())
{
getline (infile, tldTest); // sets the current TLD in the list to a string for comparision
// converts TLD to lowercase for comparison.
for(unsigned int x = 0; x<tldTest.length(); x++)
{
tldTest[x] = tolower(tldTest[x]);
transferString[x] = tldTest[x];
ValidTlds[transferString] = String(transferString);
}
}
}
}
main.cpp (缩短)
#include <iostream>
#include <fstream>
#include "String.h"
#include <map>
#include <string> // used for the allowed getline command
#include "Email.h"
#include "TldPart.h"
using namespace std;
void main()
{
string getlinetransfer; // helps transfer email from getline to c string to custom String
double emailTotal = 0.0; // Used to provide a cool progress counter
double emailCounter = 0.0; // Keeps track of how many emails have been verified.
int x = 0; // used to set c-string values, counter for loop
char * emailAddress = new char[getlinetransfer.size() + 1]; // c string used for getting info from getline.
cout << "Welcome to email validation program!" << endl;
cout << "Pre-Loading Valid TLD's..... \n" << endl;
TldPart::PreloadTLDs;
}
TldPart.h
// TldPart.h - TldPart validation class declaration
// Written by ------
#pragma once
#include "String.h"
#include <map>
#include "SubdomainPart.h"
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
class TldPart
{
public:
// MUST HAVE a defualt constructor (because TldPart is a member of Domain)
TldPart() {}
// Takes the address and stores into the Address data member
void Set(const String& address);
static void PreloadTLDs();
// Returns true when the Address is valid or false otherwise
bool IsValid();
static map<String, String> ValidTlds;
private:
String Address;
};
TldPart.cpp
// TldPart.cpp - TldPart validation class implementation
// Written by Max I. Fomitchev-Zamilov
#pragma once
#include "TldPart.h"
using namespace std;
void TldPart()
{
}
// Takes the address and stores into the Address data member
void TldPart::Set(const String& address)
{
Address = address;
}
static void PreloadTLDs()
{
bool initialized = false;
bool fileStatus = false;
string tldTest = ""; // used for getline() as allowed.
char * transferString = " "; // used to transfer chars from string to String
ifstream infile;
infile.open("ValidTLDs.txt");
fileStatus = infile.good();
if(fileStatus != true)
cout << "Cannot read ValidTLD's file. Please check your file paths and try again.";
else
{
while(!infile.eof())
{
getline (infile, tldTest); // sets the current TLD in the list to a string for comparision
// converts TLD to lowercase for comparison.
for(unsigned int x = 0; x<tldTest.length(); x++)
{
tldTest[x] = tolower(tldTest[x]);
transferString[x] = tldTest[x];
ValidTlds[transferString] = String(transferString);
}
}
}
}
// Returns true when the Address is valid or false otherwise
bool TldPart::IsValid()
{
bool tldFound = false;
map<String, String>::iterator it;
String TLDMatch;
TLDMatch = TldPart::ValidTlds.find(Address)->first;
it = TldPart::ValidTlds.find(Address);
if(it == ValidTlds.end())
tldFound == false;
else
tldFound == true;
return tldFound;
}
答:
2赞
Drew Dormann
3/13/2013
#1
此代码承诺将在某处定义单个静态变量。TldPart::ValidTlds
class TldPart
{
static map<String, String> ValidTlds;
};
加上这个,你会很好。TldPart.cpp
#include "TldPart.h"
using namespace std;
map<String, String> TldPart::ValidTlds; // DECLARE YOUR STATIC VARIABLE
void TldPart()
{
}
评论
0赞
Reciever80
3/13/2013
太棒了,这有助于解决地图 STL 的奇怪命名空间问题。对未解决的外部错误有任何想法吗?
0赞
Reciever80
3/13/2013
我应该把它放在cpp文件中的什么位置?有三个函数,一个默认构造函数,或者一个全局函数。
0赞
Reciever80
3/13/2013
它仍然给我 2001 年链接器错误,其中有 1 个未解决的外部错误。也许这与它是静态的事实有关吗?
0赞
Reciever80
3/14/2013
我有一个用于validtlds,就像以前一样,如果我更改TldPart::P reloadTlds;到 TldPart::P reloadTlds() 中,它显示存在第二个未解决的外部 2019 错误,该错误看起来像 main 中引用的预加载函数本身。可以在课后发布确切的错误。
0赞
Drew Dormann
3/14/2013
@Reciever80听起来你建错了。如果 中没有定义的东西可以使用,要么没有被编译,要么没有被链接。TldPart.cpp
评论