【问题标题】:Unresolved external symbol error while using vectors defined in a header file使用头文件中定义的向量时未解决的外部符号错误
【发布时间】:2013-06-11 11:29:39
【问题描述】:

我是 C++ 新手。我在使用向量时遇到了一个未解决的外部符号错误,不知道出了什么问题,所以我在这里复制了它。

我使用的是 MS Visual Studio 2011。确切的错误是:

错误 LNK2001:未解析的外部符号“类 std::vector > abc” (?abc@@3V?$vector@VmyClass@@V?$allocator@VmyClass@@@std@@@std@@A)

我在 myClass.h 中有我的班级声明:

#ifndef __MYCLASS__
#define __MYCLASS__

class myClass{
    public:
        int var;
        myClass(void);
        myClass (int k);
};
#endif  

以及我在 myClass.cpp 中的类定义:

#include"myClass.h"

myClass::myClass(void){
        var=0;
    }
myClass::myClass (int k){
        var=k;
    }

header.h

ifndef __HEADER__
#define __HEADER__

    #include<iostream>
    #include<vector>
    #include"myClass.h"
    using namespace std;

    extern std::vector<myClass> abc;

#endif

ma​​in.cpp

#include <iostream>
#include <vector>
#include "myClass.h"
#include "header.h"

using namespace std;

int main(){
    abc.push_back(myClass(5));

    return 1;
}

这是我得到未解决的外部符号错误的地方。现在我尝试将所有这些都放在一个文件中,并且编译正常。

以下文件未包含在上述项目中。

#include<iostream>
#include<vector>
#include"myClass.h"
using namespace std;

    class myClass{
    public:
        int var;
        myClass(void){
        var=0;
    }
    myClass (int k){
        var=k;
    }
};


int main(){
    std::vector<myClass> abc;
    abc.push_back(myClass(5));

    return 1;
}

解决方案已在What is an undefined reference/unresolved external symbol error and how do I fix it? 但我不知道如何实现它。

【问题讨论】:

    标签: c++ vector header undefined-reference


    【解决方案1】:

    您没有此向量的定义

    extern std::vector<myClass> abc;
    

    extern 声明仅告诉编译器该对象存在并且在某处定义。但是你还没有在任何地方定义它。

    在您的一个(而且只有一个!).cpp 文件中将其添加到全局命名空间范围内:

    std::vector<myClass> abc;
    

    实际上,考虑到您没有使用来自不同翻译单元(即.cpp 文件)的abc,您根本不需要extern 声明。只需将您的矢量放在main.cpp,因为这是您唯一使用它的地方。

    另外,避免使用using 指令,尤其是在命名空间范围内(因为它很容易导致与标准库中的实体发生令人讨厌的名称冲突):

    using namespace std; // THIS IS BAD, DON'T DO IT
    

    考虑到您已经对来自 std 命名空间的实体名称进行了限定,您实际上并不需要上述内容。

    【讨论】:

    • votes++ 用于使用命名空间部分。我希望人们在得到建议时能够很好地解释为什么。互联网和大量书籍使用它,因此它可能没有意义或看起来不真实。 OP 在标头中使用它,这是一种特殊情况!
    • 您能否解释一下关于命名空间的部分或解释的链接?谢谢!
    • @IBY:我编辑了答案以提示原因:如果您将实体从 std 命名空间导入全局命名空间,那么您可能会遇到错误的名称冲突。如果你有任何变量或函数或你的类命名为countfindmapdistance 等,这些名称可能突然意味着std::countstd::findstd::mapstd::distance , ...(当然取决于上下文)
    • 哦,我明白了。是的,这很清楚。假设我的代码需要经常进行限定,你会建议什么?
    • @IBY:您可以拥有using 声明,这将允许您选择个人名称(例如using std::cout; cout &lt;&lt; "Hello";)。或者,如果您认为您真的需要它,请使用像 OP 一样的 using 指令,但在尽可能小的范围内(例如函数的范围),这样其他模块(包括您的标头)就不会以该指令结束using declaration std; 将来自 std 的所有名称带入全局命名空间
    【解决方案2】:

    您将abc 声明为extern,但您从未为其提供定义。

    尝试在main.cpp中添加定义:

    #include <iostream>
    #include <vector>
    #include "myClass.h"
    #include "header.h"
    
    using namespace std;
    std::vector<myClass> abc; //^^add this line
    
    int main(){
        abc.push_back(myClass(5));
        return 1;
    }
    

    但是,恕我直言,在您的代码中使用 extern 似乎没用。同时,我认为将头文件命名为header.h 并不好。

    【讨论】:

      【解决方案3】:

      您将 abc 作为局部变量。它应该是一个全局变量。只有这样 extern 才会起作用。

      但是,如果您只想从 main() 中访问它作为局部变量,而不是从另一个编译的 CPP 文件/对象中访问,那么使用 extern 是没有意义的。仅当变量是全局变量并且要从另一个编译的 CPP/对象访问时才需要 extern。

      【讨论】:

      • 这不是问题,因为该变量仅在 main.cpp 中定义为外部变量。他并没有试图将它用作另一个单位的全局变量。
      • 添加了额外的段落。所以,extern 似乎毫无意义。
      猜你喜欢
      • 2015-01-16
      • 2016-07-10
      • 2021-02-04
      • 2013-08-07
      • 2011-09-03
      • 2010-11-20
      • 2016-11-26
      • 2012-02-28
      • 1970-01-01
      相关资源
      最近更新 更多