函数原型vs cpp包含头

igo*_*gor 4 c++ forward-declaration function-prototypes

我有功能做一些工作.

void doSomething(int n);
Run Code Online (Sandbox Code Playgroud)

A.cpp

#include "A.h"

void doSomething(int n) {
    /* something */
}   
Run Code Online (Sandbox Code Playgroud)

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

1)包括啊

B.cpp

#include "A.h"

void anotherTask() {
    // ...
    doSomething(5);
    // ...
}
Run Code Online (Sandbox Code Playgroud)

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

B.cpp

void doSomething(int);

void anotherTask() {
    // ...
    doSomething(5);
    // ...
}
Run Code Online (Sandbox Code Playgroud)

关于类的使用前向声明有很多提示.那么,功能前向声明的最佳实践是什么?

UPD

好的,这是一个太简单的例子.

如果标题啊有一些垃圾怎么办(相对于B.cpp,它对驱动程序级别一无所知):

#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 */
Run Code Online (Sandbox Code Playgroud)

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

Mat*_*son 6

在可能的情况下,始终在标题中使用原型.这可以防止意外地改变一个地方而不是另一个地方.

例如,将函数更改为:

void doSomething(long n);
Run Code Online (Sandbox Code Playgroud)

现在还有另外两个地方:功能的定义,以及b.cpp原型的改变.

如果你有一个标题,编译器至少有可能告诉你"这看起来不对劲".而不是你迟到的链接器错误...


Ian*_*dby 5

仅当该函数仅在该文件中使用时,才使用前向声明.

如果你想让它可用于其他单位你使用头文件,然后你使用前向声明(除非你正在解决一个非常具体的问题,如循环依赖).不要同时使用两者.不要在多个地方做同样的声明.

编辑

课程的前向声明与您提出的问题不同:

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

你的更新

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

也就是说,如果你对此事没有选择权,那么包含相关的头文件比复制声明更好.可维护性通常比编译速度更重要.