Language[lang]
C++ constructor: default, parameterized, copy and move
- Section
- Language [lang]
- Standard
- C++11
- Compilers
- MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2, Clang 23.1 (libc++)
- Published
- Length
- 8 min read
In this answer7 clauses
- 1What is a default constructor?
- 2What is a parameterized constructor, and can you overload constructors?
- 3What is a constructor initializer list, and why use it?
- 4What does explicit do on a constructor?
- 5What are copy and move constructors?
- 6Does a struct have a constructor in C++?
- 7Types of constructors in C++
Abstract
A C++ constructor is a member function with the same name as its class and no return type; it runs when an object is created. A default constructor takes no arguments, and the compiler stops providing one once you write any other constructor; a parameterized one takes values; copy and move constructors build an object from another. Give members their values in the initializer list, which runs in declaration order, and mark a constructor that converts from one value explicit.

A C++ constructor is a member function with the same name as its class and no return type. It runs when an object is created, to give the object its starting values. A class can have several: a default constructor takes no arguments, a parameterized one takes values, and copy and move constructors build an object from another one.
#include <iostream>
#include <string>
class Player {
public:
Player(const std::string& name, int score)
: name_(name), score_(score) {}
void print() const {
std::cout << name_ << ": " << score_ << '\n';
}
private:
std::string name_;
int score_;
};
int main() {
Player ada("Ada", 10); // the constructor runs here
ada.print(); // prints Ada: 10
}— end example]
Player ada("Ada", 10); creates the object and calls the constructor with those two values, and the part after the colon, : name_(name), score_(score), gives each member its value. The name arrives as a const std::string&, a reference to a string that the constructor can read but not change; pass by value or by const reference explains that choice.
Declared in the class as Player(const std::, the constructor is defined outside it as Player::: the initializer list goes on the definition.
Everything here works since C++11 (Since When’s C++11 table). The samples were built as C++11 with GCC 16.2 and Clang 23.1 (libc++), and as C++17 with those two, MSVC 19.44 and Clang 19.1 (MSVC STL).
What is a default constructor?
A default constructor is one that can be called with no arguments: Player p; calls it. This one sets a guest name and a score of 0:
class Player {
public:
Player() : name_("guest"), score_(0) {} // the default constructor
// ...
};
struct Counter {
int n = 0; // a default value: the compiler's constructor uses it
};
int main() {
Player p; // calls Player()
p.print(); // prints guest: 0
Counter c; // no constructor written
std::cout << c.n << '\n'; // prints 0
}— end example]
A class that declares no constructor at all, like Counter, gets a default constructor from the compiler, which acts like one with an empty body (default constructors). It leaves an int member unset unless the member has a default value in the class (a default member initializer, int n = 0;). Reading an unset member is a bug, and some compilers warn about it, not all.
Write any constructor and the compiler stops providing the default one. The first example’s Player has only the constructor with two parameters, so this line does not compile:
Player p; // error: Player has no default constructor any more— end example]
MSVC reported:
error C2512: 'Player': no appropriate default constructor available— end example]
GCC says no matching function for call to 'Player::. Write a default constructor as above, or ask for the compiler’s with Player() = default;, which, like the compiler’s own, leaves score_ unset unless it has a default value.
What is a parameterized constructor, and can you overload constructors?
A parameterized constructor is any constructor that takes arguments, such as Player(const std:: in the first example. A class can have several constructors with different parameters, which is constructor overloading, and C++ picks the one that matches the arguments. One constructor can also hand the work to another, a delegating constructor, so the initialization is written once:
class Player {
public:
Player() : Player("guest", 0) {} // delegates
Player(const std::string& name) : Player(name, 0) {} // delegates
Player(const std::string& name, int score)
: name_(name), score_(score) {} // does the work
// ...
};
int main() {
Player guest; // Player()
Player lin("Lin"); // Player(name)
Player ada("Ada", 10); // Player(name, score)
// ...
}— end example]
The three printed guest: 0, Lin: 0 and Ada: 10. A delegating constructor names the other one as the only entry of its initializer list; the target runs first, then the delegating constructor’s body.
What is a constructor initializer list, and why use it?
The constructor initializer list, also called the member initializer list, is the part after the colon: it gives each member its first value as the member is built. Assign in the constructor’s body instead, and a member of class type is first built by its default constructor, then assigned. Label is a member type that prints a line from its default constructor, its constructor from a string and its assignment; these two classes set it the two ways:
class ListPlayer {
public:
ListPlayer(const std::string& name) : name_(name) {}
private:
Label name_;
};
class BodyPlayer {
public:
BodyPlayer(const std::string& name) {
name_ = name; // name_ was already built before this line
}
private:
Label name_;
};— end example]
Building one of each from "Ada" printed:
initializer list:
Label(text)
assigned in the body:
Label()
Label = text— end example]
Some members cannot get their value by assignment: a const member or a reference member needs it in the list, or a default value in the class (constructors and member initializer lists). A const int id_; assigned in the body did not compile on any of the four.
The figure follows Player ada("Ada", 10); through the first example’s constructor, with the call’s values written where the code has the parameters:

One trap: members are initialized in the order they are declared in the class, not the order the list names them ([class.base.init]). It matters when one member’s value depends on another, or, as here, on a call that counts:
int next_number() {
static int count = 0;
return ++count; // 1 the first time, then 2
}
class Pair {
public:
// The list names second_ first, but first_ is declared first,
// so first_ is initialized first.
Pair() : second_(next_number()), first_(next_number()) {}
// ...
private:
int first_;
int second_;
};— end example]
All four printed first_ = 1, second_ = 2. GCC and Clang warn when the two orders differ, with -Wall -Wextra; MSVC at /W4 does not. Write the list in declaration order.
What does explicit do on a constructor?
A constructor that can be called with one argument also works as an implicit conversion, and explicit turns that off. This Player has Player(const std:: without explicit, and welcome() takes a const Player&. Called with a string, it compiles:
std::string name = "Ada";
welcome(name); // compiles: a temporary Player is built from name— end example]
It printed Player built from Ada, then Welcome, Ada: 0: C++ built a temporary Player, an unnamed object made for the call, without being asked. Declare the constructor explicit Player(const std:: and the same call fails on all four; MSVC says cannot convert argument 1 from 'std::. Player ada(name); still works; Player ada = name; fails like the call (explicit specifier).
Mark a constructor that takes one value of another type explicit unless you want the conversion; the overloading example’s Player(name) is one.
What are copy and move constructors?
The copy constructor builds a new object from an existing one of the same class; it runs for Player b = a; and when an object is passed by value (copy constructors). The move constructor takes over the contents of an object that is no longer needed, as in Player c = std::. Written out by hand, each prints its name:
class Player {
public:
// ...
// the copy constructor: a new Player from an existing one
Player(const Player& other)
: name_(other.name_), score_(other.score_) {
std::cout << "copy\n";
}
// the move constructor: takes over other's contents
Player(Player&& other)
: name_(std::move(other.name_)), score_(other.score_) {
std::cout << "move\n";
}
// ...
};
void show(Player player) { // by value: the argument is copied
player.print();
}
// ...
Player a("Ada", 10);
Player b = a; // copy
show(a); // copy, then Ada: 10
Player c = std::move(a); // move: a is no longer needed
b.print(); // Ada: 10
c.print(); // Ada: 10— end example]
It printed:
copy
copy
Ada: 10
move
Ada: 10
Ada: 10— end example]
Player&& is an rvalue reference; how std::move and rvalue references work has its own answer. You rarely write either constructor. The compiler writes both for a class like Player, whose members can copy and move themselves, as long as you declare no copy or move operation and no destructor: let it, which is the rule of zero. Declare a destructor and the compiler no longer writes the move constructor; std::move(a) then copies, without an error.
Does a struct have a constructor in C++?
Yes. A struct can have constructors exactly like a class; the two keywords differ in default access: a struct’s members are public, a class’s private. A struct like Size, with public members and no constructor written, can still be filled with braces, member by member:
struct Point {
Point(int x, int y) : x(x), y(y) {} // a struct constructor
int x;
int y;
};
struct Size { // no constructor
int w;
int h;
};
int main() {
Point p(3, 4); // calls Point(int, int)
Size s{3, 4}; // no constructor: braces fill w, then h
std::cout << p.x << ", " << p.y << '\n'; // 3, 4
std::cout << s.w << " x " << s.h << '\n'; // 3 x 4
}— end example]
Types of constructors in C++
| Kind | In Player |
Runs for |
|---|---|---|
| Default | Player() |
Player p; |
| Parameterized | Player(const std:: |
Player ada("Ada", 10); |
| Delegating | Player() : Player("guest", 0) {} |
Player guest; (the target runs first) |
| Converting | Player(const std:: |
welcome(name) with a string |
| Explicit | explicit Player(const std:: |
Player ada(name);, never implicitly |
| Copy | Player(const Player& other) |
Player b = a;, passing by value |
| Move | Player(Player&& other) |
Player c = std:: |
The Language section has more on classes.
Questions
Can a constructor return a value?
No. A constructor has no return type, not even void, and it cannot be called like an ordinary function: it runs when an object is created, and its job is to give that object its values.
Why does my class have no default constructor?
Because the class declares another constructor: the compiler provides a default constructor only for a class that declares none, and a copy constructor counts. Write one yourself, or ask for the compiler’s with Player() = default;, which leaves an int member without a default value unset.
What is the difference between a constructor and a destructor?
A constructor runs when an object is created; the destructor, written ~Player() for a class Player, runs when the object is destroyed. A class can have several constructors, told apart by their parameters.
Can a constructor be private?
Yes. A private constructor can be called only from inside the class (its member functions and nested classes) and by its friends, so code outside the class cannot create objects with it.
Is a member initializer list the same as std::initializer_list ?
No. The member initializer list is the part after the colon in a constructor, such as : name_(name), score_(score), which gives each member its first value. std:: is the library type that lets std::vector<int> v{1, 2, 3} take a braced list of values.
Can a constructor have default arguments?
Yes. A constructor that gives every parameter a default value can be called with no arguments, so it also serves as the class’s default constructor.
Sources
- Constructors and member initializer listscppreference.com
- Default constructorscppreference.com
- explicit specifiercppreference.com
- Copy constructorscppreference.com
- Move constructorscppreference.com
- [class.base.init] Initializing bases and membersC++ standard working draft
- [class.default.ctor] Default constructorsC++ standard working draft