C ++中的转发声明 - 当它重要吗? [英] Forward declarations in C++ - when it's matter?

查看:128
本文介绍了C ++中的转发声明 - 当它重要吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为这是C ++的精神 - 你不支付你不需要
想要(你明确支付你需要的):

  // ah 
#include< iosfwd>

template<类T>
class QVector;

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

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

// some.cpp

#includea.h

#include< iostream> //我只需要A :: print()在这个模块,而不是全接口

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

这就是为什么我认为禁止开发者工作是不公平的b $ b这种方式与STL( Will C ++ 11 STL



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



解决方案

  #include< iostream> 
#include< QVector>

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

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

我们应该把这个成语称为基本类型的接口 - module
接口的类型应该像基本类型(总是
定义和可用)?这也有意义,但仍然不清楚
什么方式更好(例如Qt混合两种方法)。



我的个人决定 - 始终提供更好的模块化方法(当我们有足够的依赖):

  // a_decl.h 
#include< iosfwd>

template<类T>
class QVector;

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

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

// ah
//如果你想使用大多数接口方法
//,并且不想写很多`#include` $ b,就包含这个文件$ b #include< iostream>
#include< QVector>

#includea_decl.h

并让开发人员选择include。



您可以对这些方法说些什么?什么方式对你更好,为什么?对于所有情况,我们是否有一个明确的获胜者,或者它总是取决于上下文?



从我与语言创建者的通信(我没有收到最后answer)



UPDATE:



定义未定义用户类型的容器(了解详情 )。

解决方案

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



创建正向头是很简单的,很大程度上是库维护者的责任。



开发人员/客户端然后可以选择使用前向头或基于他的物理头/她的需要。



大型项目肯定会喜欢并从可能的转发标题中受益。



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

我认为一个好的库维护者应该提供转发头,因为它是一个痛苦的其他人维护任何差异和更新,基于平台,版本,当项目变得适当大时,有一个明显的赢家 - 两者,你总是有选择。


I think it's a spirit of C++ - you don't pay for what you don't want ( you explicitly pay for what you need ):

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

That's why I think that it's not fair to prohibit developer to work such way with STL ( Will C++11 STL have forward declaration's files? ).

But also I see one bad thing: dependencies of module A will spread out in external context ( duplication of #include directives ) and it can lead to hard refactoring when interface will change ( e.g. replace QVector with QList - and now you need to replace all occurrences of <QVector> with <QList> ).

Solution of this problem is:

#include <iostream>
#include <QVector>

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

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

Should we call this an idiom "fundamental types of interface" - module interface's types should be like fundamentals types ( are always defined and available )? It also makes sense, but still isn't clear what way is better ( e.g. Qt mixes both approaches ).

My personal decision - always provide both ways for better modularity ( when we have enough dependencies ):

// 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"

and let developer chooses what to include.

What you can say about these approaches? What way is better for you and why? Do we have a one clear winner for all cases or it always will depend on context?

From my correspondence with language creator ( I didn't receive an final answer )

UPDATE:

With boost 1.48.0 comes Container library, which allow to define containers of undefined user types ( read more ).

解决方案

I consider both as the right approach.

Creating a forward header is simple, and much the responsibility of the library maintainer.

The developer/client can then choose to use the forward header or the physical header based on his/her needs.

Large projects will certainly favor and benefit from forward headers where possible.

Including the physical headers does not really solve dependency issues, but introduces new dependencies in many cases. e.g. "If I remove #include <string> from this header, then some compilations will fail (and could vary by the library you are using and its platform differences).

I think a good library maintainer should provide forward headers because it is a pain for others to maintain any differences and updates, based on platform, version, etc. There is a clear winner when projects become suitably large - with both, you always have choice.

这篇关于C ++中的转发声明 - 当它重要吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆