g++不同文件夹的编译

一、相同文件夹单文件

1、include “ ”引入

A文件夹里有A.h,A.cc,mainA.cc三个文件

代码

  1. ./A.h
#include <iostream>
class Afunc
{
  public:
    A();
};
  1. ./A.h
#include "A.h"
A::A()
{
  std::cout<<#include "A()"<<std::endl;
}
  1. ./mainA.cc
#include "A.h"
int main()
{
  A a;
  return 0;
}

编译指令:

  1. g++ -o mainA mainA.ccg++ -o mianA mainA.cc A.h
    报错
/tmp/ccaGpUEy.o: In function `main':
mainA.cc:(.text+0x1f): undefined reference to `A::A()'
collect2: error: ld returned 1 exit status

image.png

所以这句话的意思是在.text段中没有找到A::A()的实现。

后面的指令也也同样提示,也就说明,g++并不会根据A.h文件,自动去找它的实现A.cc
而这两条命令相同,说明include " "引入的文件,会在当前目录搜索,并自动加入。

  1. g++ -o mainA mainA.cc A.ccg++ -o mainA mainA.cc A.h A.cc
    编译通过

说明,A.h的实现文件A.cc需要显式说明,而A.h可以不用明确写出。

同时将include <iostream>改为include "iostream"也可以通过编译
说明,include " "引入的文件,会现在当前目录搜索,然后在系统制定的目录搜索。

2、include <>引入

上面的目录结构不变,将mainA.h中的#inlcude "A.h"改为#include <A.h>

编译指令

  1. g++ -o mainA mainA.cc A.cc
    报错
mainA.cc:2:15: fatal error: A.h: No such file or directory
compilation terminated.

说明include <>引入的文件,并不在当前目录搜索,只会在系统制定的目录搜索

  1. g++ -o mainA mianA.cc A.cc -I ./
    编译通过
g++ -I参数

-I可以将include <>原本的搜索目录进行扩展。
上面的语句表示将./也就是当前目录加入到其搜索目录中。至于搜索顺序,后面讨论。。

如果同时将A.cc中的include “ ”也更改,那么结果时相同的。
至于应该使用哪种方式引入,实现文件,使用哪种方式。还没找到资料。
看过别人的库,是使用的include <>引入的。

二 不同文件夹 单文件

1、include " "引入

代码

将上面的mainA.cc文件,移出A文件夹,和A文件夹放在同一级。

编译

mianA.cc所在目录进行编译

  1. g++ -o mianA main A.h A.ccg++ -o mainA mainA.cc A.cc
    报错
    分别提示
g++: error: A.cc: No such file or directory
g++: error: A.h: No such file or directory

g++: error: A.cc: No such file or directory

原因很简单,因为include " "只会在当前目录和系统指定的目录搜索,这些文件夹不包含./A文件夹,所以报错,提示未找到。

  1. #include “A/A.h”+g++ -o mainA mainA.cc A/A.c A/A.cc
    编译通过

include " "使用相对路径引入,同时在编译指令中显式的指明文件的想对路径。

必须采用既在include " "中标明路径,也在编译指令中标明路径的方式,两者有一个没有写路径,就会提示

g++: error: A.h: No such file or directory
g++: error: A.cc: No such file or directory

都会提示未找到。
为什么要指定两次?-L-I-l都不可以。

include <>

代码

mianA.cc中的include " " 改为include <>,不加路径

编译指令

  1. g++ -o main main A/A.h A/A.cc -I./A
    编译通过

这种方式不需要在include <>中显式的指明路径,但是在编译指令中仍然需要指明路径。
而系统自带的那些,并不需要在编译指令中显式指定。
但是g++ -MM mainA.cc并没有显示A.h
所以,但是这两种方式应该還是有区别的。

三 不同文件夹多文件

include" "引入

代码

  1. ./A.h
#include <iostream>
#include <C.h>
class A
{
  public:
    A();
};
  1. ./A.cc
#include <A.h>
A::A()
{
  C c;
  std::cout<<"A()"<<std::endl;
}
  1. ./A/C/C.h
#include <iostream>
class C
{
  public:
    C();
};
  1. ./A/C/C.cc
#include <C.h>
C::C()
{
  std::cout<<"C()"<<std::endl;
}
  1. ./mainA.cc
#include "A.h"
int main()
{
  A a;
  return 0;
}

文件的分布在路径里有标注。
所有的文件使用include <>引入。

编译指令

  1. g++ -o mainA mainA.cc A/A.h A/A.cc A/C/C.h A/C/C.cc -IA -IA/C
    编译通过。
    使用的是上面提到过的。使用-I将两个路径引入,这样编译器可以搜索到。
    同时,如果将include <>改为include " "也是可以编译通过的。

改变代码

改变mainA.cc代码
./mainA.cc

#include "A.h"
#include "C.h"
int main()
{
  A a;
  C c;
  return 0;
}

这样,C.h就是重复引用。报错

In file included from mainA.cc:3:0:
A/C/C.h:2:7: error: redefinition of ‘class C’
 class C
       ^
In file included from A/A.h:2:0,
                 from mainA.cc:2:
A/C/C.h:2:7: error: previous definition of ‘class C’
 class C

为了解决这个问题,所以在定义类的时候都使用如下的预处理

#ifndef C_H
#define C_H
class C
{

}
#endif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容