函数原型vs cpp中的include头

Function prototype vs include header in cpp

本文关键字:include 中的 cpp 原型 vs 函数      更新时间:2023-10-16

我有一些函数可以做一些工作。

A.h

void doSomething(int n);

A.cpp

#include "A.h"
void doSomething(int n) {
    /* something */
}   

如果我想在另一个源文件中使用这个函数,最好的选择是什么:

1) 包括A.h

B.cpp

#include "A.h"
void anotherTask() {
    // ...
    doSomething(5);
    // ...
}

2) 或者使用正向声明(函数原型):

B.cpp

void doSomething(int);
void anotherTask() {
    // ...
    doSomething(5);
    // ...
}

关于类尽可能频繁地使用正向声明,有很多技巧。那么,函数正向声明的最佳实践是什么呢?

UPD

好吧,这个例子太简单了。

如果标头A.h有一些垃圾(相对于对驱动程序级别一无所知的B.cpp)怎么办:

A.h

#include "specific_driver_header.h" /* some lowlevel stuff that B.cpp couldn't know */
#define SPECIFIC_DRIVER_DEFINES 0xF0  /* useless define for B.cpp that uses global namespace */
void doSomething(int n);   /* only significant function for B.cpp */

如果我在B.cpp中包含A.h,那么B.cpp将不是独立于驱动程序或类似的东西。在这种情况下,我应该使用变体(2)吗?

尽可能在标头中使用原型。这样可以防止意外地更改一个位置,而不是另一个位置。

例如,将函数更改为:

void doSomething(long n);

现在还有另外两个地方:函数的定义和要更改的b.cpp原型。

如果你有一个头,编译器至少会有机会告诉你"这看起来不对"。与其说你在晚些时候收到链接器错误…

只有当函数仅在该文件中使用时,我才使用正向声明。

如果你想让它对其他单元可用,你可以使用头文件,然后不使用前向声明(除非你正在解决一个非常具体的问题,比如循环依赖关系)。不要两者都用。永远不要在多个地方发表相同的声明。

编辑

类的前向声明与您询问的情况不同:

是否应该尽可能使用正向声明而不是包含?

您的更新

不要这样写头文件,这是一个简单的答案。头文件应该尽可能是自包含的,并且不包含任何与"公共"接口无关的内容。(我把"public"放在引号里,因为当你声明一个C++类时,受保护的方法和私有方法必须放在同一个"public"头文件中。但你仍然应该避免把不需要的东西放在头文件中)

也就是说,如果你在这件事上别无选择,那么最好包括相关的头文件,而不是复制声明。可维护性通常比编译速度更重要。