Defining Multiple Constructor Versions | C++ Programming

UPI Study › Courses › C++ Programming › Free lessons › Lesson 9.5 Free with a free account

Defining Multiple Constructor Versions

C++ Programming · Chapter 9: Structs, Classes, and File StreamsSection 9.5 · lesson 63 of 84video coming soon

← Initialization Inside ClassesNext lesson: Designing Clean Interfaces With Abstract Types →

Earn 3 college credits for C++ ProgrammingRecommended for credit by NCCRS · Computer Science 242 · self-paced · one payment, lifetime access

In this lesson

Flexible object creation.

  • Write several constructors, and predict which runs
  • Explain why one constructor removes the free one
  • Choose overloads or default arguments; delegate
  • Know when the copy constructor runs; fill containers

Transcript

Everything said in the video, section by section (1,357 words). Read along, or search it.

Opening Question

Objects Built From Different Starting Information

Objects of the same type aren't always created from the same starting information. A rectangle might be built from a width and a height, from a single side when it's square, or from nothing at all, when sensible defaults will do. Supplying several constructors lets a caller build the object from whatever they happen to have. And the type keeps its guarantee that every object leaves construction in a usable state.

Core Idea

One Promise From Many Starting Points

A constructor exists to make one promise. When it finishes, the object is complete and usable. Nothing outside has to remember to set a member afterward, and there's no window where the object exists but isn't ready. Offering more than one constructor doesn't weaken that promise. It means the promise can be kept from several different starting points. A rectangle with nothing, with one value, or with two: the matching constructor runs, and the result is one identically valid object. The caller supplies whatever they have. The type decides what a complete object means.

Overloading

Three Constructors Told Apart by Parameters

Constructors all carry the type's name, so they're told apart the same way any overloaded function is: by the number and types of their parameters. The compiler matches the arguments at each call against the available versions, and selects the one that fits. Here, rectangle has three constructors: one taking nothing, one taking a single side, for a square, and one taking a width and a height. Each prints a tag so we can see which runs. The first sets both sides to 1. The second sets both to the side given. So which call runs which? Rectangle a, with nothing, runs the one taking nothing, giving width and height 1. Rectangle b, with 5, runs the single-value one: width and height 5. Rectangle c, with 3 and 4, runs the two-value one. The tags in the output confirm it: zero, one, two. Differing only in parameter names is no difference at all. Two constructors each taking a single double can't coexist, whatever their parameters are called.

Common Mistake

Empty Parentheses Declare a Function

But rectangle d with empty parentheses runs nothing. It looks like a request for a default-built object, and the compiler reads it as declaring a function called d, that takes nothing and returns a rectangle. So the error arrives later, confusingly, at the first use of d. Here is what the compiler prints. Clang does warn at the declaration itself, and its note says exactly what to do: remove the parentheses. To build an object with no arguments, write no parentheses at all, or empty braces.

Common Surprise

Writing One Constructor Removes the Default

A type with no constructors at all is given one automatically: a no-argument version. The moment you write any constructor of your own, that gift is withdrawn. Here, point has only a constructor taking x and y. So declaring a plain point is refused, because there's no constructor taking nothing. And an array of 10 points is refused, 10 times over. Here are both errors. This is the most common surprise in the whole topic. Adding a convenient parameterized constructor to a type that worked perfectly well breaks every plain declaration, and every array, all at once. And the errors talk about no matching constructor, rather than about what you just did. The remedy is a deliberate decision. Either write a no-argument constructor as well, or give the parameters default values.

Default Arguments

One Constructor Replaces Three

Three constructors that differ only in how many values they accept can often be replaced by one, with defaults. Fewer versions means less to keep in step. Here, one rectangle constructor takes a width and a height, each defaulting to 1. It covers the empty call, the one-value call, and the two-value call. There's a catch, and it's a real one. Rectangle b of 5 now produces a width of 5, and a height of 1, not a square. Run it: 5 by 1. With the overloads, that call meant a square of side 5. Neither is wrong, but they're different. So choose deliberately, rather than by which is shorter to type.

Comparison

Overloads Versus Defaults Trade-Offs

Compare the two approaches. Several overloads mean one version per shape of call. One constructor with defaults means exactly one version. With overloads, a short call can mean something special: one value can mean a square. With defaults, an omitted argument always takes its stated default. Overload bodies can each do whatever they like. With defaults, there's one body for every call. The risk with overloads is duplicated work that drifts apart. The risk with defaults is a call that looks meaningful, but silently takes a default you forgot about.

Common Mistake

Mixing Defaults and Overloads Is Ambiguous

And avoid mixing both. A defaulted constructor and an overload can both match one call, and the compiler refuses it as ambiguous. Its two notes name the candidates: the defaulted version, and the one taking a single side. So for any one type, pick one approach, and never both.

Delegation

Pointing Simple Constructors at the Fullest

Where several overloads are right, they usually end up doing similar work. A delegating constructor avoids duplicating it. Instead of setting the members itself, a constructor names another constructor of the same type, and lets that one do the job. The empty constructor delegates to the two-value version with 1 and 1. The square constructor delegates with side and side. And the two-value version is the one place where the real work lives. The delegation goes in the initializer position, before the body, not as a call inside the braces. The target constructor runs first, completely. Run it: the work line appears once for each object, and the shapes come out 1 by 1 and 5 by 5. Point the simpler constructors at the fullest one, not the other way round. The fullest can express any object. The others are shorthands for particular cases of it.

Copy Constructor

Three Places Copies Are Made

One more constructor exists whether or not you write it. The copy constructor runs when a new object is built from an existing one of the same type. The supplied version copies every member across. Twin equals original is a copy construction, despite the equals sign. So is declaring also, with original in parentheses. It runs in three situations. Building an object from another is the obvious one. Passing an object to a function by value, and returning one by value, are easy to miss, because neither looks like a copy at the call site. Here the copy constructor prints, so we can count: twin, also, and the by-value call to measure. Three copies. For members that are plain values, the supplied version is correct. And writing twin equals original on a later line, where twin already exists, is assignment: a separate operation with its own rules.

Arrays and Vectors

Why Arrays Need a No-Argument Constructor

Arrays and vectors both create objects on your behalf, and each has a requirement that follows from everything above. An array of 3 rectangles builds all 3 immediately, each with no arguments. So the type needs a constructor taking nothing. Watch the first three built tags. An empty vector constructs nothing yet. Push back builds one object, then stores it in the vector. And a vector of 2 builds 2 objects, each with no arguments. That's why the array case bites hardest. A vector can stay empty until you're ready. An array can't exist without building every element at that instant. So if a type is destined to live in arrays, it needs a sensible no-argument constructor. In other words, it needs an answer to, what does an empty one look like?

Quick Check

Array of Four and Rectangle b

Quick check. A rectangle's only constructor takes a width and a height, each defaulting to one. Does an array of four rectangles compile? And what shape is rectangle b, built from two? Pause and think. Yes, the array compiles. With both values defaulted, that one constructor also serves as the no-argument version, so each element is one by one. And b is two by one, not a square: the omitted height takes its default.

Key Takeaways

Choosing, Delegating, and Copying Constructors

To summarize. Constructors are chosen by the number and types of the arguments. Writing any constructor removes the free no-argument one. Default arguments give one body, while overloads let a shorter call mean something particular. Delegate the simpler versions to the fullest. And copies are made when building from another object, passing by value, and returning by value.

About C++ Programming at UPI Study

C++ Programming (Computer Science 242) is a self-paced online course of 84 video lessons in 11 chapters, from your first program to decisions, loops, arrays, functions, classes, files, pointers and inheritance. It carries a NCCRS credit recommendation for 3 semester credits.

Every lesson transcript is free on pages like this one, and the videos are free with a free UPI Study account. Enrolling adds a practice quiz after each lesson, the graded work and final exam that earn the credit, lifetime access, and an official transcript on completion. UPI Study has helped over 130,000 students with college credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Why take it here

Why students take C++ Programming with UPI Study

Your first real programming languageC++ teaches how programs really work: variables, control flow, functions, memory and objects. It is the base for data structures, algorithms, systems and game programming, and for most computer-science degrees.
Credit at a fraction of the priceThe same 3 credits can cost $750 or more at a US college. Here it is one payment, self-paced, with lifetime access.
Finish your degree soonerTransfer credits reduce the courses you still owe, so you can graduate earlier or lighten a heavy semester.
Strengthen an applicationA completed college-level course on an official transcript shows admissions and scholarship committees you can do the work.
Study on your own scheduleNo start dates, no deadlines. Watch the lessons, practice, and take the final when you are ready.
130,000+students helped with college creditsACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Where the credit goes

Universities that work with NCCRS

C++ Programming carries a NCCRS credit recommendation. These universities work with NCCRS; some are UPI Study's signed partners. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Find my college → Not listed? Ask Athena in the corner of this page, or book a 15-minute call.

FAQ

Questions students ask us

About Defining Multiple Constructor Versions

Why does declaring Rectangle d(); not create a Rectangle object in C++?
Rectangle d(); declares a function named d that takes no arguments and returns a Rectangle, so no object is built. The confusing error appears later, at the first use of d. To create a default-constructed object, write Rectangle d; with no parentheses, or use empty braces, as in Rectangle d{};.
Why do I get a "no matching constructor" error after adding a constructor to my class?
Writing any constructor of your own removes the free no-argument constructor the compiler would otherwise supply. If Point has only Point(int x, int y), then a plain Point p; fails, and so does an array like Point pts[10];. To fix it, write a no-argument constructor too, or give the parameters default values.
Should I use overloaded constructors or default arguments in C++?
Choose based on what a short call should mean, and use only one approach per type. Overloads let one argument mean something special, such as a square, and each body can differ. Default arguments give a single body, so Rectangle(double w = 1, double h = 1) makes Rectangle b(5) a 5 by 1 shape. Mixing both can make a call ambiguous.
When does the copy constructor run in C++?
The copy constructor runs whenever a new object is built from an existing object of the same type. That happens in three cases: Rectangle twin = original; or Rectangle also(original);, passing an object to a function by value, and returning one by value. A later twin = original; is assignment, not copy construction, because twin already exists.

About the C++ Programming course

How many college credits is C++ Programming?
C++ Programming (Computer Science 242) carries a NCCRS credit recommendation for 3 semester credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.
How much does C++ Programming cost and what is included?
$250, paid once, with lifetime access: all 84 video lessons, a practice quiz after each, the graded work and final exam, and an official transcript when you finish. Students who want several courses choose UPI Study PRO instead.
Which universities accept UPI Study credits?
UPI Study has signed partner agreements with universities such as Thomas Edison State University, University of the People and Charter Oak State College, and works with universities such as Penn State, SNHU and SUNY. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities. Use "Find my college" on this page to check yours.
How long does C++ Programming take?
It is self-paced with no deadlines. The 84 lessons total about 0 hours of video; most students add reading and practice time and finish in a few weeks to a few months, on their own schedule.
How are the exams done?
Quizzes and assignments are online in the course. The final exam is taken online with proctoring; a person on the UPI Study team checks assignments, usually within two days.
How do my credits reach my college?
When the course shows 100% complete, request the official transcript from your dashboard. It is sent to the college you name, and you can send it to more than one. Check your college first with "Find my college" on this page, or ask Athena.

Ready for the full course? Earn 3 credits in C++ Programming.

84 video lessons, a quiz after each one, and the graded work that earns the credit. Recommended for credit by NCCRS.

C++ Programming
3 credits · NCCRS
Enroll →