Thursday, April 1, 2010

C++ default or copy constructor

If you implement a lot of data structure in C++, at one point you'd end up writing code that looks like this:
template<typename Tp>
class node {
 public:
  node(const Tp& value) : value_(value), next_(NULL) {}

 private:
  Tp value_;
  node<Tp> *next_;
};
The problem with this construct is that we rely on the existence of copy constructor for Tp. The author of the node class probably wanted something like this:
template<typename Tp>
class node : public Tp {
 public:
  node(...) : Tp(...), next_(NULL) {}

 private:
  node<Tp> *next_;
};
Unfortunately, C++ does not allow a subclass to inherit constructors, nor does it let us pass a variable number of arguments to the parent class constructor. A compromise is, we mandate that class Tp has a default constructor, like this:
template<typename Tp>
class node : public Tp {
 public:
  node() : Tp(), next_(NULL) {}

 private:
  node<Tp> *next_;
};
However, most templates in STL would define the node this way:
template<typename Tp>
class node {
 public:
  node(const Tp& value = Tp()) : value_(value), next_(NULL) {}

 private:
  Tp value_;
  node<Tp> *next_;
};
The benefit is that if Tp has a copy constructor, one would be used to construct private member value_; and if Tp has a default constructor, that would be used. This form relaxes the requirement that Tp would only need to provide either a default or a copy constructor.

No comments: