C++的前瞻性声明 - 什么时候重要?

Forward declarations in C++ - when it's matter?

本文关键字:什么时候 前瞻性 声明 C++      更新时间:2023-10-16

我认为这是c++的一种精神——你不为你没有的东西付出代价Want(你明确地为你需要的东西付费):

// 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 );
...

这就是为什么我认为禁止开发人员工作是不公平的(c++ 11 STL有前向声明文件吗?).

但是我也看到有一件不好的事情:模块A的依赖会在外部环境中扩散(#include指令的重复),并可能导致硬重构当接口改变时(例如用QList替换QVector -现在你需要用<QList>替换所有出现的<QVector>)

<<p> 解决方案/strong>这个问题的:
#include <iostream>
#include <QVector>
struct A
{
void process( QVector<int> );
void print( std::ostream& );
};

我们应该称它为"接口的基本类型"-模块吗接口的类型应该像基本类型(总是)定义和可用)?这也说得通,但仍不清楚哪种方法更好(例如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"

,让开发人员选择包含什么。

你对这些方法有什么看法?哪种方式对你更好,为什么?在所有情况下,我们有一个明确的赢家吗?还是总是取决于具体情况?

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

更新:

在boost 1.48.0中出现了容器库,它允许定义未定义的用户类型的容器(了解更多)

c++是一种给程序员留下了许多自由度的语言,所以在某种程度上,不可避免地会有不同的方法来做同样的事情。

在我看来,你所定义的"解决方案",即在任何。h文件中包含所有必要的include或forward声明,是为了避免"不完整的头文件"而采取的方式,我一直遵循这条规则。

有一本有趣的书,详细讨论了这样做或不这样做的利弊:《大规模c++软件设计》;由John Lakos编写,上面的规则来自哪里。

在具体谈到远期声明时,Lakos区分了"仅以名称命名"answers"仅以名称命名"。和";in-size"类用法;只有在第二种情况下,使用前向声明才是合法的(根据他的观点):

定义:如果编译函数f的函数体需要先看到T的定义,则函数f使用大小为的类型T

定义:如果编译f和f可能依赖的任何组件不需要先看到T的定义,则函数f只在名称上使用类型T

(源)

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

希望他能帮到你。

我认为这两种方法都是正确的。

创建前向头文件很简单,而且大部分是库维护者的责任。

开发人员/客户端可以根据自己的需要选择使用前向报头或物理报头。

大型项目肯定会在可能的情况下支持并受益于转发头。

包含物理头文件并不能真正解决依赖问题,但在很多情况下会引入新的依赖。如。"如果我从这个头文件中删除#include <string>,那么一些编译将失败(并且可能因您使用的库及其平台差异而异)。

我认为一个好的库维护者应该提供转发头,因为基于平台、版本等,维护任何差异和更新对其他人来说都是一件痛苦的事情。当项目规模足够大时,有一个明显的赢家——两者都有,你总是有选择的余地。