【问题标题】:How to properly include Header and Implementation Files?如何正确包含头文件和实现文件?
【发布时间】:2015-08-07 21:02:28
【问题描述】:

我是 C++ 的新手程序员,我目前遇到编译错误

Undefined symbols for architecture x86_64

据说这源于头文件和实现文件的包含/编码方式。

下面是一些生成我收到的编译错误的代码


主要

//Main.cpp
#include <iostream>
#include <string>
#include "Animal.hpp"

using namespace std;

int main(){
    Animal myPet;
    myPet.shout();

    return 0;
}

标题

//Animal.hpp
#ifndef H_Animal
#define H_Animal

using namespace std;

#include <string>

class Animal{
public:
    Animal();

    void shout();
private:
    string roar;
};
#endif

实施

//Animal.cpp
#include "Animal.hpp"
#include <string>

Animal::Animal(){
    roar = "...";
}

void Animal::shout(){
    roar = "ROAR";
    cout << roar;
}

此代码生成我的编译问题。如何解决这个问题?

感谢您的宝贵时间


编辑

Undefined symbols for architecture x86_64:
  "Animal::shout()", referenced from:
      _main in test-5f7f84.o
  "Animal::Animal()", referenced from:
      _main in test-5f7f84.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

【问题讨论】:

  • 您能否更具体地说明您的编译器给您的错误信息是什么?
  • 仅仅包含头文件是不够的,您需要将每个 .cpp 编译成一个目标文件,然后将这些目标文件的所有链接在一起。鉴于您发布的内容,您似乎只是在编译和链接 main.cpp。
  • 显示你传递给 clang 的参数
  • @Nicholas Hayden 好的,如果你有三个文件,test.cpp(有 main)、animal.cpp 和 animal.hpp。命令应该是g++ animal.cpp test.cpp。您需要编译所有源文件。

标签: c++ header-files


【解决方案1】:

也许您可能希望查看 3 个文件的替代集合,其中的内容更加“排序”,您知道,内容被放置在它们“真正”属于的位置。

所以这里是“新”头文件..

//Animal.hpp
#ifndef H_Animal
#define H_Animal

#include <string> // suffices

// Interface.
class Animal {
    std::string roar; // private

public:
    Animal();
    void shout();
};

#endif

然后是源文件..

//Animal.cpp
#include "Animal.hpp"

#include <iostream> // suffices

// Constructor.
Animal::Animal()
    :
    roar("...") // data member initializer
{}

// Member function.
void Animal::shout() {
    roar = "ROAR";
    std::cout << roar;
}

和主程序..

//Main.cpp
#include "Animal.hpp"

int main(){
    Animal thePet;
    thePet.shout(); // outputs: `ROAR'
}

加上一点 GNU makefile ..

all: default run

default: Animal.cpp Main.cpp
    g++ -o Main.exe Animal.cpp Main.cpp

run:
    ./Main.exe

clean:
    $(RM) *.o *.exe

在您的命令行中输入“make”即可启动。你喜欢它吗? -- 问候,M。

【讨论】:

    【解决方案2】:

    我只能在你的代码中找到一个错误,而你的编译器应该已经告诉你了。

    Animal.cpp 中,您使用的是std::cout,但您不是#includeing &lt;iostream&gt;。您在Main.cpp#include 它,但那里不需要它。

    如果您(真的)想在Animal.cpp 中将std::cout 称为cout,您还必须在该文件中添加using namespace std 指令。

    头文件 (Animal.hpp) 中的 using 指令是邪恶的。摆脱它并输入std::string。将 using 指令放入标头中会导致所有使用它的文件的命名空间。

    我也不明白你对roar 成员的意图。在构造函数中分配"..." 并在每次调用shout 时重新分配"ROAR" 有什么意义?难道你不能没有那个变量而简单地拥有

    void
    Animal::shout()
    {
      std::cout << "ROAR\n";
    }
    

    ?我添加了一个换行符,因为您可能想要一个。

    【讨论】:

    • 首选语法是using std::cout;,而不是包括整个命名空间。
    【解决方案3】:

    @JamesMoore 解决了我在这个编码项目中遇到的主要问题。

    "@Nicholas Hayden 好的,如果你有三个文件,test.cpp(有 main)、animal.cpp 和 animal.hpp。命令应该是 g++ animal.cpp test.cpp。你需要编译所有源文件。”

    我目前没有使用 IDE。所以,当我调用编译器来编译我的 main.cpp 时 - 这是编译实现文件的问题。

    g++ test.cpp
    

    需要成为

    g++ test.cpp animal.cpp
    

    这将调用编译器来编译程序所需的所有内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-05
      • 2017-08-27
      • 1970-01-01
      • 2018-10-01
      • 2014-04-28
      • 2010-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多