如何正确地包含头文件和实现文件

How to properly include Header and Implementation Files?

本文关键字:文件 实现 包含头 正确地      更新时间:2023-10-16

我是一个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)

也许你可能想要看到你的3个文件的另一组,其中的东西更"排序",你知道,在那里的东西被放在他们"真正"属于的地方。

所以这是"new"头文件..

//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 .

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

Animal.cpp中,您使用的是std::cout,而不是#include<iostream>。您在Main.cpp#include它,但那里不需要它。

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

头文件中的using指令(Animal.hpp)是邪恶的。去掉它并输入std::string。将using指令放在头文件中会破坏所有使用它的文件的命名空间。

我也不明白你对roar成员的意图。在构造函数中将"..."赋值给它,并在每次调用shout时将"ROAR"重新赋值给它,这有什么意义?你能不能去掉这个变量,只写

void
Animal::shout()
{
  std::cout << "ROARn";
}

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

我在这个编码项目中遇到的主要问题是由@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

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