我想更好地了解编译c ++时链接程序如何工作。
如果我在多个cpp文件中定义函数或全局变量,则会收到多个定义的链接器错误。这是有道理的,因为我有多个版本,并且链接器无法确定特定的版本。为了避免这种情况,只能写/包括声明(仅函数签名,变量外部签名)。但是,我注意到您可以在类声明中定义方法,并且至少在这里大多数人认为对于琐碎的函数(例如琐碎的getter和setter)可以接受甚至是很好的做法,因为它允许编译器内联这些函数(并且,这对于模板是必要的。)>
在有关“一次编译指示”的讨论中,我知道在某些情况下,工具链将无法区分文件是否相同,因此,原则上,两个cpp文件可能会获得同一类从不同的标头声明的名称,但是对此类仅标头方法定义不同,不是吗?
我试图建立一个例子:main.cpp
#include <iostream> #include "Class1.hpp" #include "Class2.hpp" using namespace std; int main() { Class1 c1; Class2 c2(c1); c1.set(1); cout << c1.get() << endl; c2.print(); return 0; }
Class1.cpp:
#pragma once #ifndef CLASS1_HPP #define CLASS1_HPP #warning Class1 class Class1 { public: void set(int i) { val = i; }; int get() {return val;}; int val=0; }; #endif
Class1a.hpp
#pragma once #ifndef CLASS1_HPP #define CLASS1_HPP #warning Class1a class Class1 { public: void set(int i) { val = i; }; int get() {return -1*val;}; int val=0; }; #endif
Class2.hpp:
#pragma once #ifndef CLASS2_HPP #define CLASS2_HPP #include <iostream> #include "Class1a.hpp" using namespace std; class Class2 { public: Class2(Class1 &c1) : c1(c1) {}; void print(); Class1& c1; }; #endif
Class2.cpp
#include "Class2.hpp" void Class2::print() { cout << c1.get() << endl; }
但是,我得到以下输出:
$ g++ *.cpp; ./a.out In file included from Class2.hpp:6:0, from Class2.cpp:1: Class1a.hpp:4:2: warning: #warning Class1a [-Wcpp] #warning Class1a ^~~~~~~ -1 -1
我不太清楚为什么预编译器从来没有看到Class1(not-a),尽管它实际上是在main.cpp中首先包含的,所以我想我的问题扩展到了那个……
我想更好地了解编译c ++时链接程序如何工作。如果我在多个cpp文件中定义一个函数或一个全局变量,则会收到多个定义的链接器错误。这使得...
链接器根本不处理头文件。编译器(在预处理阶段)以文本形式将标头的内容插入源文件。然后编译生成的翻译单元。