default
The default
keyword in C++ is a powerful feature introduced in C++11. It's primarily used in the context of special member functions, allowing the compiler to generate default implementations. This keyword enhances code readability and helps prevent unintended behavior.
#include <iostream>
class SimpleClass {
public:
SimpleClass() = default;
void printMessage() {
std::cout << "Hello from SimpleClass!" << std::endl;
}
};
int main() {
SimpleClass obj;
obj.printMessage();
return 0;
}
In this example, we use default
to explicitly request the compiler to generate a default constructor for SimpleClass
. This is equivalent to writing an empty constructor but more expressive and potentially more efficient.
#include <iostream>
#include <string>
class Person {
public:
Person(const std::string& name) : name_(name) {}
// Defaulted copy constructor
Person(const Person&) = default;
// Defaulted copy assignment operator
Person& operator=(const Person&) = default;
void printName() const {
std::cout << "Name: " << name_ << std::endl;
}
private:
std::string name_;
};
int main() {
Person p1("Alice");
Person p2 = p1; // Uses defaulted copy constructor
Person p3("Bob");
p3 = p1; // Uses defaulted copy assignment operator
p1.printName();
p2.printName();
p3.printName();
return 0;
}
default
for both the copy constructor and copy assignment operator.default
, we explicitly tell the compiler to generate these special member functions with their default behavior.#include <iostream>
#include <vector>
class DataHolder {
public:
DataHolder(std::vector<int> data) : data_(std::move(data)) {}
// Defaulted move constructor
DataHolder(DataHolder&&) = default;
// Defaulted move assignment operator
DataHolder& operator=(DataHolder&&) = default;
// Deleted copy operations to enforce move semantics
DataHolder(const DataHolder&) = delete;
DataHolder& operator=(const DataHolder&) = delete;
void printData() const {
for (int i : data_) {
std::cout << i << " ";
}
std::cout << std::endl;
}
private:
std::vector<int> data_;
};
int main() {
DataHolder d1({1, 2, 3, 4, 5});
DataHolder d2 = std::move(d1); // Uses defaulted move constructor
DataHolder d3({6, 7, 8});
d3 = std::move(d2); // Uses defaulted move assignment operator
d3.printData();
return 0;
}
default
for move operations (move constructor and move assignment operator).default
and delete
can be used together to control special member functions.#include <iostream>
#include <memory>
class Resource {
public:
Resource() { std::cout << "Resource acquired" << std::endl; }
~Resource() { std::cout << "Resource released" << std::endl; }
};
class Manager {
public:
Manager() : resource_(std::make_unique<Resource>()) {}
// Defaulted destructor
~Manager() = default;
private:
std::unique_ptr<Resource> resource_;
};
int main() {
{
Manager m;
std::cout << "Manager object created" << std::endl;
} // Manager and Resource destructors called here
std::cout << "End of main" << std::endl;
return 0;
}
default
for the destructor.std::unique_ptr
) which doesn't require explicit deletion, we use = default
to explicitly state that we want the compiler-generated destructor.Rule of Zero: When possible, rely on the Rule of Zero, which states that you should avoid declaring special member functions if the default behavior is sufficient.
Inheritance: Be cautious when using default
in inheritance hierarchies. A defaulted destructor in a base class, for example, will not be virtual unless explicitly declared as such.
Performance: Using default
can sometimes lead to more efficient code than manually implementing the same functionality, as the compiler has more freedom to optimize.
The default
keyword in C++ is a powerful tool for explicitly requesting compiler-generated implementations of special member functions. It's commonly used for constructors, destructors, copy/move operations, and assignment operators. By using default
, you can:
Understanding and properly using the default
keyword is crucial for writing clean, efficient, and maintainable C++ code, especially when dealing with resource management and object lifecycle.