设为首页 加入收藏

TOP

为什么不推荐在头文件中直接定义函数?(二)
2023-07-23 13:25:21 】 浏览:57
Tags:文件中
用了这个头文件,那么当头文件修改后,所有引用头文件的源文件都要重新编译,对于大型项目非常耗时

  • 第二种:把函数的定义和声明放在不同的文件中。这样做可以使得当源文件中定义的函数发生修改时,只需要重新编译被修改的源文件就可以了,不需要所有引用这个头文件的源文件重新编译,节省了非常多的时间


  • 为什么在头文件中定义的函数发生改变时,所有包含该头文件的源文件需要重新编译?

    还是借用以上的例子,我的猜想是这样的

    假如在 main.cpp 源文件中引用 math.h 头文件,相当于把头文件中的内容复制到了源文件里

    那么如果 math.h 头文件中定义函数,并且 main.cpp 源文件中引用了 math.h 头文件,则相当于把 math.h 中的定义的函数复制到 main.cpp 源文件里,一旦头文件中的函数发生改变,那么就相当于源文件发生了改变

    因此所有包含 math.h 头文件的源文件都需要重新编译

    此外,多个源文件包含同一个定义函数的头文件,会导致重定义的错误。这里只是举个例子假设编译器允许这样的操作,实际上编译不会通过

    img

    调用函数时的索引顺序:

    在源文件中调用函数的时候,是先到头文件里找声明的函数,然后再通过链接的过程找到对应的源文件里的函数

    如下图所示,main.cpp 调用函数时,先到 math.h 中找到声明的函数,然后再通过链接的过程找到对应的源文件 math.cpp 里的函数

    img

    这个过程可以看作是查字典,头文件相当于目录,对应着每个函数所在的位置


    2.3 可读性与安全性

    在头文件中写函数的定义会降低代码的可读性和可维护性,如果这个头文件包含了很多函数的定义。比如,假设有一个头文件 utils.h,其中定义了一些工具类的函数:

    // utils.h
    #include <string>
    #include <vector>
    using namespace std;
    
    string trim(string s) {
        // some code to trim the whitespace of s
    }
    
    vector<string> split(string s, char delim) {
        // some code to split s by delim
    }
    
    string join(vector<string> v, char delim) {
        // some code to join v by delim
    }
    
    bool is_number(string s) {
        // some code to check if s is a number
    }
    
    int to_int(string s) {
        // some code to convert s to int
    }
    
    string to_string(int x) {
        // some code to convert x to string
    }
    

    这个头文件包含了很多函数的定义,这会让代码看起来很冗长,也不容易找到想要的函数。而且,如果我们想要修改或添加某个函数的实现细节,比如改进 trim 函数的效率,那么我们就需要修改头文件 utils.h。但是这样会影响到所有包含了这个头文件的源文件,也会增加代码的复杂度和出错的风险。为了解决这个问题,我们应该把函数的定义放在另一个源文件 utils.cpp 中,然后在头文件中只声明函数:

    // utils.h
    #include <string>
    #include <vector>
    using namespace std;
    
    string trim(string s); // 函数声明
    vector<string> split(string s, char delim); // 函数声明
    string join(vector<string> v, char delim); // 函数声明
    bool is_number(string s); // 函数声明
    int to_int(string s); // 函数声明
    string to_string(int x); // 函数声明
    
    // utils.cpp
    #include "utils.h"
    
    string trim(string s) {
        // some code to trim the whitespace of s
    }
    
    vector<string> split(string s, char delim) {
        // some code to split s by delim
    }
    
    string join(vector<string> v, char delim) {
        // some code to join v by delim
    }
    
    bool is_number(string s) {
        // some code to check if s is a number
    }
    
    int to_int(string s) {
        // some code to convert s to int
    }
    
    string to_string(int x) {
        // some code to convert x to string
    }
    
    首页 上一页 1 2 下一页 尾页 2/2/2
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇C++将WSAGetLastError转换成字符.. 下一篇C++子类的构造函数

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目