解析C++多文件编程问题

针对"解析C++多文件编程问题",这里提供一份完整攻略,希望能够解决大家的疑惑。

什么是C++多文件编程问题?

在C++编程中,当你需要引用多个.cpp文件中的函数和变量时,你会发现编译器会提示未定义或者找不到引用的参数。这时,你需要将相关的头文件引入进来,在编译器中进行链接,才能解决这个问题。

解决C++多文件编程问题的方法

C++ 多文件编程的解决方法主要有以下四种:

  1. 将所有代码放入同一个文件中。这种方法虽然简单,但是当项目规模扩大时,维护起来就比较麻烦。因此,我们不推荐使用这种方法。

  2. 在每个.cpp文件中都引入包含所有变量和函数的头文件。这种方法可以解决 C++ 多文件编程问题,但是会因为编译多余的代码而造成性能浪费。

  3. 使用 extern 声明所有需要引用的函数或变量。这种方法的核心是将所有需要引用的变量或者函数,在被引用时使用 extern 进行声明。这种方法虽然看起来简单明了,但是对于工程规模比较大的项目而言,需要手动的声明的量非常大而且容易出错。

  4. 使用 Makefile 或 CMakefile 来管理编译链接。这种方法是最好的解决方案,因为它可以自动化管理,大大减轻了工作量和出错概率,适用于大型项目。

Makefile / CMakefile具体用法

下面,以使用 Makefile 或 CMakefile 来管理编译链接为例,详细讲解具体用法。

Makefile

Makefile 的主要作用是告诉编译器我们需要编译的文件、头文件、库文件、生成的目标文件以及链接的目标。

首先,我们假设我们有两个需要编译的 C++ 源代码文件,分别为 main.cpp 和 child.cpp,之间有函数相互调用。现在我们需要将它们链接起来生成可执行文件。

  1. 创建一个 makefile 文件。在该目录下创建一个新的文件,命名为 Makefile。

  2. 添加变量。我们需要使用变量记录 C++ 源文件的位置,以及最终生成的可执行文件名称。Makefile 可以使用如下变量:

CC = g++
MAIN = main
CHILD = child
OBJ = $(MAIN).o $(CHILD).o
TARGET = $(MAIN)

这里,我们定义了编译器 CC 为 g++,MAIN 和 CHILD 记录了两个 C++ 源代码文件的名称,OBJ 记录了最终生成的目标文件名称,TARGET 记录了最终生成的可执行文件的名称。

  1. 添加编译规则。添加如下代码:

```
$(TARGET) : $(OBJ)
$(CC) -o $@ $^

$(MAIN).o : $(MAIN).cpp
$(CC) -c $(MAIN).cpp

$(CHILD).o : $(CHILD).cpp
$(CC) -c $(CHILD).cpp
```

在这里,我们定义了三个规则:$(MAIN).o、$(CHILD).o 和 $(TARGET)。其中,$(MAIN).o 和 $(CHILD).o 的规则比较简单,就是通过 $(CC) 编译命令生成对应的目标文件。而 $(TARGET) 是我们最终需要的可执行文件,它的规则即为将 $(MAIN).o 和 $(CHILD).o 目标文件链接在一起,生成最终的可执行文件。

  1. 执行编译。在终端输入命令 make。

$ make

然后,make 工具会读取 Makefile 文件中的指令,按照我们写的编译规则生成最终的可执行文件。

CMakefile

CMake 是一个高效、跨平台、开源的建立和管理逐步复杂的代码项目的工具,可以自由的生成所需的 Makefile/CMakefile 以及跨平台的编译环境,同时也支持用户编写自己的编译规则。

  1. 创建 CMakeLists.txt 文件。

  2. 在 CMakeLists.txt 文件中,使用 add_executable 添加需要编译的 C++ 源文件:

add_executable(hello main.cpp child.cpp)

  1. 使用 target_link_libraries 添加外部库文件的链接信息(可选):

target_link_libraries(hello libxxx.so)

  1. 执行编译。在终端输入命令 cmake。然后,使用命令 make 生成最终的可执行文件。

$ cmake .
$ make

示例

下面,提供两个示例,分别是 Makefile 示例和 CMakefile 示例。

Makefile 示例

文件结构如下:

├── Makefile
├── child.cpp
└── main.cpp

child.cpp 文件内容如下:

#include "child.hpp"
#include <iostream>

void Child::speak() {
    std::cout << "This is Child speak.\n";
}

child.hpp 文件内容如下:

#ifndef CHILD_HPP
#define CHILD_HPP

class Child {
public:
    void speak();
};

#endif

main.cpp 文件内容如下:

#include "child.hpp"

int main() {
    Child child;
    child.speak();

    return 0;
}

Makefile 内容如下:

CC = g++
MAIN = main
CHILD = child
OBJ = $(MAIN).o $(CHILD).o
TARGET = $(MAIN)

$(TARGET) : $(OBJ)
    $(CC) -o $@ $^

$(MAIN).o : $(MAIN).cpp
    $(CC) -c $(MAIN).cpp

$(CHILD).o : $(CHILD).cpp
    $(CC) -c $(CHILD).cpp

.PHONY : clean

clean :
    rm $(OBJ) $(TARGET)

执行 make 命令即可编译链接生成可执行文件。

CMakefile 示例

文件结构如下:

├── CMakeLists.txt
├── child.cpp
├── child.hpp
└── main.cpp

child.cpp 文件内容如下:

#include "child.hpp"
#include <iostream>

void Child::speak() {
    std::cout << "This is Child speak.\n";
}

child.hpp 文件内容如下:

#ifndef CHILD_HPP
#define CHILD_HPP

class Child {
public:
    void speak();
};

#endif

main.cpp 文件内容如下:

#include "child.hpp"

int main() {
    Child child;
    child.speak();

    return 0;
}

CMakeLists.txt 文件内容如下:

cmake_minimum_required(VERSION 3.0)

project(CPP_FILE)

add_executable(hello main.cpp child.cpp)

执行 cmake . 命令,然后执行 make 命令即可编译链接生成可执行文件。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:解析C++多文件编程问题 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C++代码实现链队列详解

    C++代码实现链队列详解 什么是链队列? 链队列是一种基于链表实现的队列,它克服了顺序队列需要进行元素搬移的缺点,具有入队和出队均可以在O(1)时间内完成的优点。 链队列的数据结构 链队列的数据结构主要由节点结构体和队列结构体两部分组成。 节点结构体 节点结构体主要包括当前节点存储的数据和指向下一个节点的指针。 template <typename T…

    C 2023年5月23日
    00
  • Sublime Test怎么运行C语言程序? Sublime执行C语言的技巧

    下面是详细的攻略。 Sublime Text怎么运行C语言程序? Sublime Text是一款优秀的代码编辑器,提供了丰富的插件和工具,可以方便地编辑、编译和运行C语言程序。以下是Sublime Text运行C语言程序的步骤: 安装编译器:Sublime Text本身并不支持C语言程序编译和运行,需要先安装C语言编译器,推荐使用MinGW-w64(Wind…

    C 2023年5月23日
    00
  • C语言访问特殊用途的地址

    我来详细讲解一下C语言访问特殊用途的地址的完整使用攻略。 什么是特殊用途地址 特殊用途地址(Special Purpose Address)是指在计算机系统中被用于特定目的的内存地址。在C程序中,可以通过这些地址来访问一些系统资源,如输入输出端口、内存映射设备等。 常见的特殊用途地址包括两种:物理地址和虚拟地址。物理地址是指直接映射到物理内存的地址,而虚拟地…

    C 2023年5月10日
    00
  • .cgd是什么文件,cgd文件用什么程序打开和删除的方法

    .cgd是一个加密的文件格式,通常是由“加密工具”或“加密驱动器”创建的。这种文件格式被用于保护个人或机密的数据,如个人照片、视频、文档等。 CGD文件格式 .cgd文件格式使用AES 256位进行加密,这使得文件在被传输或存储时变得更加安全可靠。 打开CGD文件 .cgd文件必须通过相应的软件才能被打开。这些软件被称为“加密工具”或“加密驱动器”。 我们推…

    C 2023年5月23日
    00
  • 详解C++中的const关键字及与C语言中const的区别

    详解C++中的const关键字及与C语言中const的区别 const 基础知识 在 C++ 中,const 关键字表示“常量”,即标识符被定义为只读的,不可修改的量。定义常量的格式如下: const <type> <name> = <value>; 其中,<type> 可以是任何 C++ 数据类型,<n…

    C 2023年5月23日
    00
  • C语言 strncpy()函数

    下面是关于 C 语言中 strncpy() 函数的详细使用攻略: 一、函数简介 strncpy() 函数是 C 语言中的字符串复制函数,它可以复制指定长度的字符串,并返回目标字符串地址。 函数原型如下: char* strncpy(char* dest, const char* src, size_t n); 参数说明:- dest:目标字符串,拷贝后的字符…

    C 2023年5月9日
    00
  • OpenCV mask的作用及如何制作掩模mask

    OpenCV的mask是一个二进制图像,用于控制对另一个图像的操作。在图像处理中,掩模通常被用于选择感兴趣区域(ROI)或执行像素级别的操作,如图像增强、滤波、混合等。 制作掩模实际上就是创建一个二值图像,其中像素值为0或255(黑或白),作用是将掩模图像中为255的像素区域与原图像中对应位置的像素进行操作,在区域内进行所需的图像处理操作。 下面我们以制作掩…

    C 2023年5月23日
    00
  • C语言用指针支持树

    关于“C语言用指针支持树”的完整使用攻略,我准备分为以下几个部分进行讲解: 树的定义与基本操作 使用指针实现树节点 树的遍历算法 示例程序 树的定义与基本操作 树是一种非常常见的数据结构,其结构非常清晰,由若干个节点组成,每个节点之间有唯一的父子关系。 一些常见的树操作包括: 插入节点:在树中插入一个新节点,将其作为指定节点的子节点。 删除节点:从树中删除给…

    C 2023年5月9日
    00
合作推广
合作推广
分享本页
返回顶部