0

好的如果需要,我会添加代码,但通常我很体面地计算出错误。然而,我得到的这个很混乱。我正在使用三个文件。驱动程序代码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是相当大的,而且只会是去筛选一个烂摊子。这是我的问题吗?

+0

需要更多信息来解决潜在的问题。 –

+0

我可以猜测你把'map_of_cities'的主体放在标题中吗? – chris

+0

听起来像您可能需要(除其他外)在utils.h文件中使用include-guard。基本上,这是使用'#ifdef'来避免文件被多次包含的技巧。我应该想象一下,用多种定义解决你的问题。 – enhzflep

回答

1

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

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

对于您的情况,您将获得util目标文件,该文件引用city::~city()city::city()

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

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

+0

对不起,你可以解释一下这一点。我从来没有真正处理过链接,所以我不知道我在做什么。我在utils.h文件中有一个构造函数和解构器。是否期望我也可以在utils.cpp中定义它们。我猜你可能需要查看我的代码才能确定。我正在使用一个make文件来编译提供给我的文件(这是为了一个类项目,但是id喜欢学习真正为我自己使用的)。 –

+0

我已添加更多详细信息。希望有帮助。 – Daniel