dwoodwardgb
dwoodwardgb

Reputation: 174

How to "default constructor" in C++

There's a problem I've been running into lately and since I'm a self taught C++ programer I'd really like to know how professionals in the real world solve it.

Is it a good idea to write a default constructor for all classes? Aren't there certain parts of the STL that won't work if your classes don't have default constructors?

IF SO, then how does one write a default constructor that does sensible things? That is, how can I assign default values to my private members if there simply are not sensible default values? I can only think of two solutions:

  1. Use pointers (or unique_ptrs) for each member and that way a nullptr means the field is uninitialized.

OR

  1. Add extra fields/logic/methods to do the work of checking to see whether or not a field has been initialized and rely on that (think kind of like unique_ptr's "reset" method).

How do people solve problems like this in the real world?

Upvotes: 2

Views: 226

Answers (3)

5gon12eder
5gon12eder

Reputation: 25459

Is it a good idea to write a default constructor for all classes?

No. If there is no sensible “default value” for your type, you should not write a default constructor. Doing so would violate the principle of least surprise.

That said, many types do have a sensible default value.

  • the number zero (more generally: the neutral element)
  • the empty string
  • an empty list
  • a 0 × 0 matrix
  • the time-zone UTC ± 00:00

For such types, you really should define a default constructor.

Other types don't have a natural default value but have an “empty” state that can be reached by performing certain operations. It is sensible to default-construct such an object to have that state.

  • an I/O stream disconnected from any source / sink that fails every operation (can be reached by reaching the end of the file or encountering an I/O error)
  • a lock guard that doesn't hold a lock (can be reached by releasing the lock)
  • a smart pointer that doesn't own an object (can be reached by releasing the managed object)

For these types, it is a trade-off whether to define a default constructor. Doing so does no harm but makes your type slightly more complicated. If it is a public type found in a library, then it is probably worth the trouble. If you're going to implement a move constructor (and assignment operator) anyway, you can equally well define the default constructor to construct the object in a state that would be reached by moving away from it.

For other types, you just cannot define a sensible default.

  • a day of the week
  • a name for a baby

Do not invent an artificial “null” state for these types just to make them default-constructible. Doing so complicates the code and forces you to provide less useful class invariants as you could without that artificial state. If somebody really needs that additional state, they can easily use an optional<T> but going the other way round is not possible.

Aren't there certain parts of the STL that won't work if your classes don't have default constructors?

Yes. std::vector::resize is probably the most prominent example. But don't worry about these. If your type does not have a sensible default value, performing that operation isn't meaningful either. It's not the fault of your type. It's inherent to the nature of the concept you're trying to model.

Upvotes: 1

aschepler
aschepler

Reputation: 72463

If it doesn't make sense for your data type to have a default constructor, then don't write one.

(STL is long dead, but I assume you mean the standard library.) Most standard library containers work well even if the contained type doesn't have a default constructor. Some notable gotchas:

  • std::vector<T>::resize(n) requires T to have a default constructor. But without one, you can use erase and insert instead.

  • std::map<K,V>::operator[] and std::unordered_map<K,V>::operator[] require V to have a default constructor. But without one, you can use find and insert instead.

Upvotes: 2

Revolver_Ocelot
Revolver_Ocelot

Reputation: 8783

Is it a good idea to write a default constructor for all classes?

No. Sometimes there is no sense in having default values for object.

Aren't there certain parts of the STL that won't work if your classes don't have default constructors?

There are some parts which require DefaultConstructible objects. And there are ways to circumvent it (overloads which takes a object to use instead of default constructed).

Upvotes: 0

Related Questions