Channels ▼

Andrew Koenig

Dr. Dobb's Bloggers

Teaching C++ Badly: Introduce Constructors and Destructors at the Same Time

May 12, 2011

We continue with last month's summary of how not to teach C++ by discussing constructors and destructors.

For years, I used to teach constructors, destructors, copy constructors, and copy assignment at the same time — and very early in the curriculum. My reasoning was straightforward: These four special member functions interact with each other in ways that often cause them to be used together, so why not cover them together? I originally intended that question to be rhetorical; it took me years to realize that it really had an answer.

The answer is that constructors really serve two different purposes. One purpose is shared by all constructors: Ensure that the object under construction meets the requirements implied by the initial value that the user wishes to give it. The other purpose is both optional and subtle: Sometimes, a constructor allocates memory or another resource.

Only in this second case is a destructor necessary. If the only purpose of a constructor is to ensure that the object under construction has an appropriate initial value, we can dispense with the destructor. For example:

struct Point {
    Point(double x = 0, double y = 0) x(x), y(y) { }
    double x, y;
    // No destructor needed
};

This simple class violates two principles that one normally associates with well written C++ programs:

  • It has public data members.
  • Its constructor has parameters with the same names as its data members.

Nevertheless, each time I see it, I find myself liking it more as a pedagogical example.

I suppose that what I am about to say borders on heresy, but I see nothing wrong a priori with a class with public data members. You may cry, "But it's not encapsulated!" but I will answer, "You're right. So what?" This is a very simple class with an interface that is fundamentally the same as its implementation. The reason I've written it as a class at all is just one of notational convenience: I want to be able to write

Point p;

or

Point q(3.14, 2.72);

without having to give each point's data members initial values in separate assignment statements.

The constructor of this little class exists purely for the purpose of initialization. You may object that the constructor is confusing because writing x(x) uses x twice in close proximity to refer to two different objects; but I think this usage is no more confusing than writing

*p++ = *q++;

Once you've seen it a few times and become comfortable with it, it no longer presents a comprehension problem.

Anyway, in this example, the constructor allocates no resources — so there is no need for a destructor. This would be true even if x and y were of types, such as vector, that themselves allocated resources. Under the new C++ standard, such types include smart pointers, reducing even further the circumstances under which classes need destructors. Therefore, it makes sense — at least to me — to defer the discussion of destructors to the point at which students have a better grasp of resource allocation and deallocation.

The moment you start talking about destructors, it is essential that you also talk about copy constructors and copy assignment. The reason is that you don't need a destructor unless your constructors allocate resources that the destructor must deallocate (except for a null virtual destructor that's needed for the root class of an inheritance hierarchy — but that's a completely different issue that deserves to be treated separately). Using a destructor, therefore, implies that your class is deallocating a resource.

When you write a class with constructors that allocate a resource and destructors that deallocate it, you have to answer the question of what happens to the resource when you copy an object of that class. If copying an object does not duplicate its resource, then destroying the original object and then destroying its copy will deallocate the same resource twice. If copying the object does duplicate the resource, that duplication is not going to happen by itself — the programmer has to arrange to duplicate it. That's part of the point of a copy constructor, just as allocating the resource in the first place is part of the point of other constructors.

Therefore, my current thinking about how to teach constructors and destructors is:

  • Start by teaching about constructors that have the sole purpose of initializing objects of their class and do not allocate separate resources.
  • Discuss the notion of resource allocation separately, explaining how a constructor can allocate a resource that a destructor deallocates.
  • As part of the discussion of resource allocation, raise the issue of what happens when an object is copied, and how to arrange for resources to be duplicated as necessary.

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 


Video