#include <iostream>
#include <ostream>
#include <list>
#include "a.h"
#include "b.h"
#include "c.h"
#include "d.h"
#include "e.h"
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);
}
-- Remove <iostream> People automatically include <iostream>, even if
input functions never used.
-- Replace <ostream> with <iosfwd> Parameters and return types only need
to be forward declared. Because ostream is basic_ostream<char> template,
it is not enough to declare.
-- Replace "e.h" with forward declaration of class E.
-- Leave "a.h" and "b.h": we need a full declaration of the base classes
in case of inheritance. The compiler must know the size of bases,
whether functions are virtual or not.
-- Leave "c.h" and "d.h": list<C> and D are private data members of X.
#include <iosfwd>
#include <list>
#include "a.h"
#include "b.h"
#include "c.h"
#include "d.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);
}
class X
{
private:
class XImpl *pimpl_;
};
struct XImpl
{
};
Advantages:
-- Types mentioned only in a class's implementation need no longer be defined
for client code, wich eliminate extra #includes and improve compile speed.
-- A class's implementation can be changed - private members can be added
or removed - without replacing client code.
Costs:
-- Each construction/destruction must allocate/deallocate memory.
-- Each access of a hidden member can require at least one extra indirection.
Sometimes from the hidden part we must access members in visible part:
that we need another extra indirection.
#include <iosfwd>
#include "a.h"
#include "b.h"
class C;
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:
class XImpl *pimpl_;
};
inline std::ostream& operator<<( std::ostream& os, const X& x)
{
return x.print(os);
}
#include "x.h"
#include "c.h"
#include "d.h"
struct XImpl
{
std::list<C> clist_;
D d_;
};
#include <iosfwd>
#include "a.h"
class C;
class E;
class X : public A
{
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:
class XImpl *pimpl_;
};
inline std::ostream& operator<<( std::ostream& os, const X& x)
{
return x.print(os);
}
#include "x.h"
#include "b.h"
#include "c.h"
#include "d.h"
struct XImpl
{
B b_;
std::list<C> clist_;
D d_;
};