CPP Idioms
目录

1. The Rule of Three

The Rule of Three is a rule of thumb for C++, basically saying, if your class needs either:

  • a copy constructor,
  • an assignment operator,
  • or a destructor,

then it is likely to need all three of them.

The default semantics for these three member functions are:

  • Destructor: Call the destructors of all the object's class-type members
  • Copy constructor: Construct all the object's members from the corresponding members of the copy constructor's argument, calling the copy constructors of the object's class-type members, and doing a plain assignment of all non-class type (e.g., int or pointer) data members
  • Copy assignment operator: Assign all the object's members from the corresponding members of the assignment operator's argument, calling the copy assignment operators of the object's class-type members, and doing a plain assignment of all non-class type (e.g., int or pointer) data members.

Reference:

2. Copy-and-Swap

The copy-and-swap idiom is the solution, and elegantly assists the assignment operator in achieving two things:

  1. avoiding code duplication with copy constructor;
  2. providing a strong exception guarantee;
// traditional
T& operator=(const T& rhs)
{
T temp(rhs);       // create temporary local data of the data, may throw exception
swap(*this, temp); // swap the old data with the local new data
return *this;
// temporay local data destructs with old data destruct
}

Copy-and-swap idiom need three things:

  • a working copy-constructor
  • a working destructor
  • a non-throwing swap function.(should not use std::swap()), more about this see Effective CPP Q25

So as to The Rule of Three, the assignment operator can be write in form automatically by adding a swap function.

If you're going to make a copy of something in a function, let the compiler do it in the parameter list.

// better
T& operator(T rhs)     // don't need enter the function if construction of the copy fails
{
swap(*this, rhs);
return *this;
}

Reference:

  • http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom

3. Pointer to implementation (Pimpl)

The pimpl idiom is a modern C++ technique to hide implementation, to minimize coupling(耦合), and to separate interfaces. This technique is described in Design Patterns as the Bridge pattern. It is sometimes referred to as:

  • "handle classes",
  • the "Pimpl idiom" (for "pointer to implementation idiom"),
  • "Compiler firewall idiom"
  • or "Cheshire Cat",

especially among the C++ community.

Here's how the pimpl idiom can improve the software development lifecycle:

  • Minimization of compilation dependencies.
  • Separation of interface and implementation.
  • Portability.
// .h
class Handler {
public:
Handler();
void foo1();
int foo2();

Handler(const Handler& other);
Handle& Handle::operator=(const Handle &other);

private:
class HandlerImpl;          // 私有,对用户隐藏此类
std::tr1::unique_ptr<HandlerImpl> pimpl;   // 用于深拷贝,shared_prt用于浅拷贝
};
// .c
class Handler::HandlerImpl {
public:
...
HandlerImpl() {...}         // 修改函数实现,不需要重新编译用户代码
HandlerImpl(const HandlerImpl&) {...}
void foo1() {...}
int foo2() {...}
...
};

Handler::Handler()
: pimpl(new HandlerImpl)
{
...
}

Handler::Handler(const Handler& other)
: pimple(new HandlerImpl(*(other.pimpl)))   // 深拷贝
{
...
}

Handler& Handler::operator=(Handler other)
{
swap(*this, other);
return *this;
}

void Handler::foo1() {
pimpl->foo1();
}

int Handler::foo2() {
return pimpl->foo2();
}

Reference:

  • http://en.wikipedia.org/wiki/Opaque_pointer
  • http://c2.com/cgi/wiki?PimplIdiom‎
  • http://msdn.microsoft.com/en-us/library/vstudio/hh438477.aspx

发表评论