【问题标题】:Confusing compiler error令人困惑的编译器错误
【发布时间】:2014-03-07 03:06:06
【问题描述】:

好的,如果需要,我会添加代码,但通常我很擅长找出错误。然而,我得到的这个非常令人困惑。我正在使用三个文件。一个驱动程序代码 citysim.cpp,以及两个支持文件 utils.cpp 和 utils.h。我猜这是因为我在他们之间协调时做错了什么。

报错如下

g++ -g -Wall -o citysim citysim.o utils.o
utils.o: In function `map_of_cities::read(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
/home/rryder1/cs302/labs/lab4/utils.cpp:95: multiple definition of `map_of_cities::read(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
citysim.o:/home/rryder1/cs302/labs/lab4/utils.h:61: first defined here
citysim.o: In function `map_of_cities::read(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
citysim.cpp:(.text+0xcb): undefined reference to `city::city()'
citysim.cpp:(.text+0x244): undefined reference to `city::~city()'
citysim.cpp:(.text+0x2a3): undefined reference to `city::~city()'
citysim.o: In function `std::vector<city, std::allocator<city> >::_M_insert_aux(__gnu_cxx::__normal_iterator<city*, std::vector<city, std::allocator<city> > >, city const&)':
citysim.cpp:(.text._ZNSt6vectorI4citySaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_[std::vector<city, std::allocator<city> >::_M_insert_aux(__gnu_cxx::__normal_iterator<city*, std::vector<city, std::allocator<city> > >, city const&)]+0xd2): undefined reference to `city::~city()'
citysim.cpp:(.text._ZNSt6vectorI4citySaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_[std::vector<city, std::allocator<city> >::_M_insert_aux(__gnu_cxx::__normal_iterator<city*, std::vector<city, std::allocator<city> > >, city const&)]+0x27d): undefined reference to `city::~city()'
citysim.o: In function `__gnu_cxx::new_allocator<city>::destroy(city*)':
citysim.cpp:(.text._ZN9__gnu_cxx13new_allocatorI4cityE7destroyEPS1_[__gnu_cxx::new_allocator<city>::destroy(city*)]+0x18): undefined reference to `city::~city()'
citysim.o:citysim.cpp:(.text._ZSt8_DestroyI4cityEvPT_[void std::_Destroy<city>(city*)]+0x14): more undefined references to `city::~city()' follow
utils.o: In function `map_of_cities::read(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
utils.cpp:(.text+0xacd): undefined reference to `city::city()'
utils.cpp:(.text+0xc68): undefined reference to `city::~city()'
utils.cpp:(.text+0xcc7): undefined reference to `city::~city()'
collect2: ld returned 1 exit status

它可能源于的一件事是我不确定如何将 utils.cpp 与 utils.h 链接,或者我是否需要。我习惯将所有内容都写在一个 cpp 文件中。 utils.cpp 和 citysim.cpp 都包含 utils.h 的包含语句。 utils.h 基本上只有类定义和函数头。 utils.cpp 包含所有函数定义,citysim.cpp 包含主函数。

这是我的 utils.h 文件

#ifndef __CITY_DEFS_H__
#define __CITY_DEFS_H__

#include <string>
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <iomanip>
using namespace std;

//#include ALL HEADER FILES NEEDED FOR THIS HEADER FILE

class city {
  friend ostream &operator<<(ostream &, const city &);
  //OTHER FRIENDS
  friend class map_of_cities;
  public:
    city();
    ~city();

    // MEMBER FUNCTIONS
  protected:
    // MEMBER DATA

    string Name, type;
    float latitude, longitude;
    int population, listlocation;


    // MEMBER FUNCTIONS
};


ostream &operator<<(ostream &, const city &);

//OTHER CLASS DEFINITIONS
class map_of_cities {
    public:
        map_of_cities();
        ~map_of_cities();

        void read(string fname);
        float distance(city one, city two);
        void populatelists();
        void print();
        int listpop(vector<city> list);

    private:
        vector<city> cities;
        vector<city> local;
        vector<city> regional;
        vector<city> global;
};

#endif

如果我需要包含其他文件,但 utils.cpp 非常大,筛选起来会很麻烦。这是我的问题吗?

【问题讨论】:

  • 需要更多信息来解决根本问题。
  • 我猜你把map_of_cities 的正文放在了标题中吗?
  • 听起来您可能需要(除其他外)在您的 utils.h 文件中使用包含防护。基本上,这是一个使用#ifdef 的技巧,可以防止文件被多次包含。我应该想象一下,用多个定义解决你的问题。
  • 好的,我添加了头文件,如果这有助于缩小问题范围。我很感激任何帮助,特别是如果你能解释出了什么问题,而不是仅仅告诉我修复。虽然我会修复哈哈

标签: c++ compiler-construction compiler-errors linker header-files


【解决方案1】:

这不是编译器错误,而是链接错误。您没有被链接的“城市”类的构造函数或析构函数。确保在运行 c++ 命令时包含两个 cpp 文件,或者在编译后分离出链接阶段。

构建 C++ 项目涉及多个阶段。两个重要的阶段是“编译”和“链接”。编译器获取每个 C++ 文件并生成一个“对象”文件。目标文件包含所有定义的符号(类、函数、方法、全局变量等)。部分目标文件可能引用不在原始目标文件中的其他符号。

在您的情况下,您将拥有 util 对象文件,该文件引用 city::~city()city::city()

在编译阶段,源代码还可以引用将在另一个对象中的符号。通常 .h 文件用于提供有关符号的信息,但通常它们不包括实际符号本身。在您的情况下,util.h 拼出“这个程序作为城市构造函数和析构函数”,但它实际上并没有提供

正如您在评论中所说,您确实需要将它们添加到“util.cpp”中,以提供链接器可以找到的实际实现。

【讨论】:

  • 抱歉,您能否再解释一下。我从来没有真正处理过链接,所以我不知道我在做什么。我在 utils.h 文件中有一个构造函数和解构函数。是否期望我也在 utils.cpp 中定义它们。我猜您可能需要查看我的代码才能确定。我正在使用提供给我的 make 文件进行编译(这是一个类项目,但我想了解我自己使用的真正情况)。
  • 我添加了更多细节。希望这会有所帮助。
猜你喜欢
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多