如何正确包含标头和实施文件?

时间:2015-08-07 21:02:29

标签: c++ header-files

我是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 个答案:

答案 0 :(得分:2)

也许你可能想看到你的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

点击你的cmd行中只需“make”的东西。你喜欢它吗? - 此致,M。

答案 1 :(得分:1)

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

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

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

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

我也不理解你对roar成员的意图。在构造函数中为"..."分配"ROAR"并在每次调用shout时为其重新分配void Animal::shout() { std::cout << "ROAR\n"; } 有什么意义?难道你不能没有那个变量而只是拥有

                    var relation = user.relation("habits");
                    relation.add(newHabit);

                    user.save().then(function(success) {
                        response.success("success!");
                    });

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

答案 2 :(得分:1)

我对这个编码项目的主要问题由@JamesMoore解决。

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

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

g++ test.cpp

需要成为

g++ test.cpp animal.cpp

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