c++ - C++ 中的前向声明——什么时候重要?

标签 c++ forward-declaration

<分区>

我认为这是 C++ 的精神——不为不为所欲为 想要(你明确支付你需要的东西):

// a.h
#include <iosfwd>

template< class T >
class QVector;

struct A
{
void process( QVector<int> );

void print( std::ostream& );
};

// some.cpp

#include "a.h"

#include <iostream> // I need only A::print() in this module, not full interface

...
A().print( std::cout );
...

这就是为什么我认为禁止开发人员工作是不公平的 这种方式与 STL ( Will C++11 STL have forward declaration's files? )。

但我也看到了一件坏事:模块 A 的依赖性 将在外部上下文中传播(#include 指令的重复)并且它可能导致硬重构 界面何时更改(例如,将 QVector 替换为 QList - 现在您需要将所有出现的 <QVector> 替换为 <QList>)。

解决这个问题:

#include <iostream>
#include <QVector>

struct A
{
void process( QVector<int> );

void print( std::ostream& );
};

我们是否应该将其称为成语“接口(interface)的基本类型” - 模块 接口(interface)的类型应该像基础类型(总是 定义和可用)?也有道理,但还是不清楚 哪种方法更好(例如 Qt 混合了这两种方法)。

我个人的决定 - 始终提供两种方式以获得更好的模块化(当我们有足够的依赖性时):

// a_decl.h
#include <iosfwd>

template< class T >
class QVector;

struct A
{
void process( QVector<int> );

void print( std::ostream& );
};

// a.h
// Include this file if you want to use most interface methods
// and don't want to write a lot of `#include`
#include <iostream>
#include <QVector>

#include "a_decl.h"

并让开发者选择要包含的内容。

您对这些方法有何看法?哪种方式更适合您,为什么?对于所有案例,我们是否都有一个明显的赢家,还是始终取决于具体情况?

来 self 与语言创造者的通信(我没有收到最终答复)

更新:

随着 boost 1.48.0 的推出,Container 库允许定义未定义用户类型的容器 ( read more )。

最佳答案

C++ 是一种为程序员留下许多自由度的语言,因此不可避免地会有不同的方法来做同一件事。

IMO,你定义的“解决方案”,即在任何 .h 文件中包含所有必要的包含或前向声明,是避免“不完整的头文件”的方法,我一直遵循这条规则。

有一本有趣的书全面讨论了这样做或不这样做的所有利弊:"Large-Scale C++ Software Design" by John Lakos ,上面的规则来自哪里。

特别谈到前向声明时,Lakos 区分了“in-name-only”和“in-size”类用法;只有在第二种情况下,(根据他的意见)使用前向声明才是合法的:

Definition: A function f uses a type T in size if compiling the body of f requires having first seen the definition of T.

Definition: A function f uses a type T in name only if compiling f and any of the components on which f may depend does not require having first seen the definition of T.

( source )

具体来说,Lakos 的推理围绕着某些 C++ 编程风格对大型系统(即具有一定复杂性的系统)的影响展开,但我认为他的建议也非常适合任何规模的系统。

希望他的帮助。

关于c++ - C++ 中的前向声明——什么时候重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8028526/

相关文章:

c++ - 具有静态 unique_ptr 的单例是一个好习惯吗

c++ - 这个回文划分算法的时间复杂度是多少?

c++ - 如何使用环境变量转换路径(例如 %temp%)

c++ - 不调用复制赋值运算符=

c++ - 两个类和内联函数

c - 为什么结构的前向声明不起作用?

c++ - for(;;) 和 while(1) 有什么区别?

c++ - 用 `using` 定义的类型的前向声明

javascript - Javascript 中不明确的函数声明

c++ - 为什么 VS2017 会警告 "Function definition not found"对于使用输入 typedef 声明但使用原始定义的函数向前?