Không. Khi bạn định nghĩa bất kỳ constructor nào (constructor có tham số, copy constructor, move constructor...), trình biên dịch không còn tự động tạo constructor mặc định (default constructor) nữa.
Ví dụ 1: Không có constructor do người dùng định nghĩa
#include <iostream>
using namespace std;
class MyInteger {
private:
int value;
// Không có constructor nào được định nghĩa
};
int main() {
MyInteger I1; // OK: Compiler tự tạo default constructor MyInteger()
return 0;
}
Kết quả: Biên dịch thành công.
Ví dụ 2: Có constructor do người dùng định nghĩa
#include <iostream>
using namespace std;
class MyInteger {
private:
int value;
public:
MyInteger(int v) { // User-defined constructor
value = v;
}
};
int main() {
MyInteger I1; // LỖI: Không có default constructor!
return 0;
}
Kết quả: Lỗi biên dịch error: no matching function for call to 'MyInteger::MyInteger()'.
Cách khắc phục
Nếu muốn cả constructor có tham số VÀ default constructor, hãy định nghĩa tường minh default constructor:
class MyInteger {
private:
int value;
public:
MyInteger() : value(0) {} // Default constructor tường minh
MyInteger(int v) : value(v) {} // Constructor có tham số
};
Tóm tắt quy tắc
| Trường hợp | Compiler tạo default constructor? |
|---|---|
| Không định nghĩa constructor nào | CÓ (public, inline, không tham số, không khởi tạo thành viên) |
| Định nghĩa bất kỳ constructor nào | KHÔNG |
| Chỉ định nghĩa copy/move constructor | KHÔNG |
Định nghĩa constructor có tham số mặc định (vd: MyInteger(int v=0)) | KHÔNG (nhưng constructor đó có thể gọi không đối số) |
C++11: = default và = delete
class MyClass {
public:
MyClass() = default; // Yêu cầu compiler tạo default constructor
MyClass(const MyClass&) = delete; // Cấm copy constructor
MyClass(int x) { ... }
};