Item 26. Minimizing Compile-time Dependencies part 1

I l@ve RuBoardPrevious Section Next Section

Item 26. Minimizing Compile-time Dependencies桺art 1

Difficulty: 4

When we talk about dependencies, we usually think of run-time dependencies like class interactions. In this Item, we will focus instead on how to analyze and manage compile-time dependencies. As a first step, try to identify (and root out) unnecessary headers.

Many programmers habitually #include many more headers than necessary. Unfortunately, doing so can seriously degrade build times, especially when a popular header file includes too many other headers.

In the following header file, which #include directives could be immediately removed without ill effect? You may not make any changes other than removing or rewriting #include directives. Note that the comments are important.

//  x.h: original header 
//
#include <iostream>
#include <ostream>
#include <list>
// None of A, B, C, D or E are templates.
// Only A and C have virtual functions.
#include "a.h"  // class A
#include "b.h"  // class B
#include "c.h"  // class C
#include "d.h"  // class D
#include "e.h"  // class E
class X : public A, private B
{
public:
     X( const C& );
  B  f( int, char* );
  C  f( int, C );
  C& g( B );
  E  h( E );
  virtual std::ostream& print( std::ostream& ) const;
private:
  std::list<C> clist_;
  D            d_;
};
inline std::ostream& operator<<( std::ostream& os, const X& x )
{
  return x.print(os);
}
  •  
 
I l@ve RuBoardPrevious Section Next Section
 
I l@ve RuBoardPrevious Section Next Section

Solution

graphics/bulb_icon.gif

Of the first two standard headers mentioned in x.h, one can be immediately removed because it's not needed at all, and the second can be replaced with a smaller header.

  1. Remove iostream.

    #include <iostream> 
    

    Many programmers #include <iostream> purely out of habit as soon as they see anything resembling a stream nearby. X does make use of streams, that's true; but it doesn't mention anything specifically from iostream. At the most, X needs ostream alone, and even that can be whittled down.

    Guideline

    graphics/guideline_icon.gif

    Never #include unnecessary header files.


  2. Replace ostream with iosfwd.

    #include <ostream> 
    

    Parameter and return types need only to be forward-declared, so instead of the full definition of ostream we really only need its forward declaration.

In the old days, you could just replace "#include <ostream>" with "class ostream;" in this situation, because ostream used to be a class and it wasn't in namespace std. Alas, no more. Writing "class ostream;" is illegal for two reasons.

  1. ostream is now in namespace std, and programmers aren't allowed to declare anything that lives in namespace std.

  2. ostream is now a typedef of a template; specifically, it's typedef'd as basic_ostream<char>. Not only would the basic_ostream template be messy to forward-declare in any case, but you couldn't reliably forward-declare it at all, because library implementations are allowed to do things like add their own extra template parameters (beyond those required by the standard), which, of course, your code wouldn't know about梠ne of the primary reasons for the rule that programmers aren't allowed to write their own declarations for things in namespace std.

    All is not lost, however. The standard library helpfully provides the header iosfwd, which contains forward declarations for all the stream templates (including basic_ostream) and their standard typedefs (including ostream). So all we need to do is replace "#include <ostream>" with "#include <iosfwd>".

    Guideline.

    graphics/guideline_icon.gif

    Prefer to #include <iosfwd> when a forward declaration of a stream will suffice.


    Incidentally, once you see iosfwd, one might think that the same trick would work for other standard library templates, such as list and string. There are, however, no comparable "stringfwd" or "listfwd" standard headers. The iosfwd header was created to give streams special treatment for backward compatibility, to avoid breaking code written in years past for the "old" nontemplated version of the iostreams subsystem.

    There, that was easy. We can…

    What? "Not so fast!" I hear some of you say. "This header does a lot more with ostream than just mention it as a parameter or return type. The inlined operator<< actually uses an ostream object! So it must need ostream's definition, right?"

    That's a reasonable question. Happily, the answer is: No, it doesn't. Consider again the function in question:

    inline std::ostream& operator<<( std::ostream& os, const X& x ) 
    {
    return x.print(os);
    }
    

    This function mentions an ostream& as both a parameter and a return type (which most people know doesn't require a definition), and it passes its ostream& parameter in turn as a parameter to another function (which many people don't know doesn't require a definition either). As long as that's all we're doing with the ostream&, there's no need for a full ostream definition. Of course, we would need the full definition if we tried to call any member functions, for example, but we're not doing anything like that here.

    So, as I was saying, we can get rid of only one of the other headers just yet.

  3. Replace e.h with a forward declaration.

    #include "e.h"  // class E 
    

Class E is just being mentioned as a parameter and as a return type, so no definition is required, and x.h shouldn't be pulling in e.h in the first place. All we need to do is replace "#include "e.h"" with "class E;".

Guideline

graphics/guideline_icon.gif

Never #include a header when a forward declaration will suffice.


  •  
 
I l@ve RuBoardPrevious Section Next Section
基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型,个人经导师指导并认可通过的高分设计项目,评审分99分,代码完整确保可以运行,小白也可以亲自搞定,主要针对计算机相关专业的正在做大作业的学生和需要项目实战练习的学习者,可作为毕业设计、课程设计、期末大作业,代码资料完整,下载可用。 基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值