C++;使用不同的源知道在main.cpp之外使用哪个类 我试图理解C++的理解,我想知道MIN .CPP如何知道我构建的类是否在另一个源文件中?编译器是否自动知道如果我在类中包含带有函数参数的头文件,它将在main.cpp之外的所有源文件中查找它

C++;使用不同的源知道在main.cpp之外使用哪个类 我试图理解C++的理解,我想知道MIN .CPP如何知道我构建的类是否在另一个源文件中?编译器是否自动知道如果我在类中包含带有函数参数的头文件,它将在main.cpp之外的所有源文件中查找它,c++,C++,编译器不知道。因此,您必须手动将所有已编译的对象文件添加到将可执行文件链接在一起的命令中 gcc(和其他编译器)很乐意用一个编译器调用编译多个文件,在这种情况下,它将合并所有编译的对象。或者,您可以编译多个文件,还可以提供用于链接的对象文件 但是不管你怎么做,你都有责任指出所有文件的位置。编译器不知道。因此,您必须手动将所有已编译的对象文件添加到将可执行文件链接在一起的命令中 gcc(和其他编译器)很乐意用一个编译器调用编译多个文件,在这种情况下,它将合并所有编译的对象。或者,您可以编译多个文件

编译器不知道。因此,您必须手动将所有已编译的对象文件添加到将可执行文件链接在一起的命令中

gcc
(和其他编译器)很乐意用一个编译器调用编译多个文件,在这种情况下,它将合并所有编译的对象。或者,您可以编译多个文件,还可以提供用于链接的对象文件


但是不管你怎么做,你都有责任指出所有文件的位置。

编译器不知道。因此,您必须手动将所有已编译的对象文件添加到将可执行文件链接在一起的命令中

gcc
(和其他编译器)很乐意用一个编译器调用编译多个文件,在这种情况下,它将合并所有编译的对象。或者,您可以编译多个文件,还可以提供用于链接的对象文件


但是不管你怎么做,你都有责任指出所有文件的位置。

简短回答:它不知道

长答案: 假设您有以下文件:

main.cpp A.h A.cpp 调用此命令编译
main.cpp
时:

g++ -c main.cpp -o main.o
g++ -c A.cpp -o A.o
你的编译器相信你的话,方法
A::f
是在其他地方定义的。但实际上编译器并不知道,它只是信任

稍后,调用此命令编译
A.cpp

g++ -c main.cpp -o main.o
g++ -c A.cpp -o A.o
此时,编译器不知道如何使用这个类(它不知道
main.cpp
main.o

执行此命令时,所有“链接魔法”都会发生:

g++ main.o A.o -o ./myexe
这时,
linker
中发生了神奇的事情,它发现
main.o
引用了在其他地方定义的名为
A
的类,然后它找到了一个名为
A.o
的文件,其中包含同名
A
的类的定义。因此,它发现这个类和那个
A
类是相同的,并进行了适当的链接

当然,如果您不想执行这三个命令,您不需要执行这三个命令,因为以下命令是等效的:

g++ main.cpp A.cpp -o ./myexe

简短回答:它不知道

长答案: 假设您有以下文件:

main.cpp A.h A.cpp 调用此命令编译
main.cpp
时:

g++ -c main.cpp -o main.o
g++ -c A.cpp -o A.o
你的编译器相信你的话,方法
A::f
是在其他地方定义的。但实际上编译器并不知道,它只是信任

稍后,调用此命令编译
A.cpp

g++ -c main.cpp -o main.o
g++ -c A.cpp -o A.o
此时,编译器不知道如何使用这个类(它不知道
main.cpp
main.o

执行此命令时,所有“链接魔法”都会发生:

g++ main.o A.o -o ./myexe
这时,
linker
中发生了神奇的事情,它发现
main.o
引用了在其他地方定义的名为
A
的类,然后它找到了一个名为
A.o
的文件,其中包含同名
A
的类的定义。因此,它发现这个类和那个
A
类是相同的,并进行了适当的链接

当然,如果您不想执行这三个命令,您不需要执行这三个命令,因为以下命令是等效的:

g++ main.cpp A.cpp -o ./myexe

<> P>一件事,你应该用C++来理解——没有什么是自动的:-)< /P> 我假设您是在IDE中工作的,因为使用GNU命令行工具无法不理解这一步

基本上,您的工具链配置为知道在哪些目录中搜索源文件,以及在哪些目录中搜索头文件。预处理器现在负责使用
#include
指令中指示的路径连接头文件(除非指定标准头,否则它将搜索可配置的目录列表)

编译cpp文件时,它会生成一个对象文件。这个对象文件可以引用它还不知道的类型-链接阶段处理连接

这里有一个例子

给定以下文件:

特殊类

#ifndef SPECIAL_CLASS_H_
#define SPECIAL_CLASS_H_
class SpecialClass {
  private:
    unsigned int x;
  public:
    SpecialClass();
    /** Increment the 'x' value and return it */
    int incrementAndReturn();
};
#endif 
SpecialClass.cpp

#include "SpecialClass.h"

int SpecialClass::incrementAndReturn() {
  return this->x++;
}

SpecialClass::SpecialClass() {
  this->x = 0;
}
main.cpp

#include <iostream>

/**
 * By including SpecialClass.h, the compiler can enforce the contract
 * outlined in the SpecialClass header. That is, if I try to use a
 * method or member that doesn't exist in the SpecialClass type, then
 * the compiler can warn me.
 */
#include "SpecialClass.h"
int main(int, char**) {

  SpecialClass foo = SpecialClass();
  std::cout << foo.incrementAndReturn() << std::endl;
} 
此时,main.cpp已被编译和组装,但与SpecialClass.cpp中定义的代码没有链接-它已取消链接

rdahlgren@athas:~/work/cpp $ g++ -c SpecialClass.cpp
rdahlgren@athas:~/work/cpp $ ls -l
total 20
-rw-r--r-- 1 rdahlgren rdahlgren  410 Feb 26 23:49 main.cpp
-rw-r--r-- 1 rdahlgren rdahlgren 2672 Feb 26 23:50 main.o
-rw-r--r-- 1 rdahlgren rdahlgren  139 Feb 26 23:50 SpecialClass.cpp
-rw-r--r-- 1 rdahlgren rdahlgren  222 Feb 26 23:46 SpecialClass.h
-rw-r--r-- 1 rdahlgren rdahlgren 1448 Feb 26 23:51 SpecialClass.o
rdahlgren@athas:~/work/cpp $ g++ main.o SpecialClass.o -o main
您可以在这里看到,我现在有了SpecialClass和main的对象文件(*.o)。这些都经过编译和组装,但没有链接

rdahlgren@athas:~/work/cpp $ g++ -c SpecialClass.cpp
rdahlgren@athas:~/work/cpp $ ls -l
total 20
-rw-r--r-- 1 rdahlgren rdahlgren  410 Feb 26 23:49 main.cpp
-rw-r--r-- 1 rdahlgren rdahlgren 2672 Feb 26 23:50 main.o
-rw-r--r-- 1 rdahlgren rdahlgren  139 Feb 26 23:50 SpecialClass.cpp
-rw-r--r-- 1 rdahlgren rdahlgren  222 Feb 26 23:46 SpecialClass.h
-rw-r--r-- 1 rdahlgren rdahlgren 1448 Feb 26 23:51 SpecialClass.o
rdahlgren@athas:~/work/cpp $ g++ main.o SpecialClass.o -o main
GCC能够将如上所示的对象文件链接在一起,这将绑定对
incrementAndReturn
(以及其他)的调用


<>为了更好的解释,我建议使用您最喜欢的Web搜索来查找关于“C++编译步骤”的信息。

< P> >您应该在C++早期了解到什么是自动的:-)< /P> 我假设您是在IDE中工作的,因为使用GNU命令行工具无法不理解这一步

基本上,您的工具链配置为知道在哪些目录中搜索源文件,以及在哪些目录中搜索头文件。预处理器现在负责使用
#include
指令中指示的路径连接头文件(除非指定标准头,否则它将搜索可配置的目录列表)

编译cpp文件时,它会生成一个对象文件。这个对象文件可以引用它还不知道的类型-t