小学生学C++编程语法知识(什么情况下会自动生成默认构造函数)
对于小学生,可以先记住一句话:
如果我们没有写任何构造函数,C++ 编译器可能会偷偷帮我们生成一个默认构造函数;但是一旦我们自己写了某些构造函数,编译器通常就不再自动生成。
下面详细讲解。
一、什么是默认构造函数?
先看一个类:
class Student { };我们没有写任何东西。
但是:
Student s;为什么可以创建对象?
因为编译器偷偷帮我们生成了:
class Student { public: Student() { } };这个没有参数的构造函数:
叫:
默认构造函数(default constructor)
二、什么时候会自动生成默认构造函数?
主要有以下情况。
情况1:类里面完全没有构造函数
这是最常见情况。
例如:
class Student { public: int age; };我们没有写:
Student() { }那么编译器会自动生成:
Student() { }所以:
Student s;可以。
但是注意:
自动生成的默认构造函数:
不会自动给普通变量初始化。
例如:
class Student { public: int age; }; int main() { Student s; cout << s.age; }这里:
s.age里面是什么?
不确定!
因为:
int age;没有初始化。
可能:
123456也可能:
0也可能:
垃圾值情况2:类有成员对象,但自己没有构造函数
例如:
class Book { }; class Student { public: Book b; };Student没有构造函数。
编译器生成:
Student() { }但是创建 Student:
Student s;时:
必须先创建:
Book b;所以调用:
Book()如果 Book 有默认构造函数:
没问题。
三、什么时候不会自动生成默认构造函数?
这是考试重点。
情况1:自己写了带参数构造函数
例如:
class Student { public: Student(int x) { } };现在:
我们自己写了构造函数。
那么:
编译器认为:
“你已经设计好了,我不帮你了。”
所以:
不会生成:
Student() { }因此:
Student s;错误。
因为:
没有:
Student()但是:
这样可以:
Student s(10);因为:
匹配:
Student(int)情况2:自己写了拷贝构造函数
例如:
class Student { public: Student(const Student& s) { } };我们自己写了:
拷贝构造函数。
编译器:
不会生成默认构造函数。
所以:
Student a;错误。
但是:
Student b(a);可以。
四、课堂练习题:
看:
class A { }; class B { public: B(int x) { } };问:
下面哪些可以自动生成默认构造函数?
1.
A a;可以。
为什么?
因为:
A没有任何构造函数。
自动生成:
A()2.
B b;错误。
因为:
B自己写了:
B(int)所以:
没有:
B()3.
B b(5);可以。
因为:
调用:
B(int)五、为什么 C++ 这样设计?
同学们可以理解成:
编译器像一个助手:
如果你说:
“我什么都没安排。”
编译器:
“好,我帮你安排一个最简单的。”
但是如果你说:
“我要学生必须输入年龄才能创建。”
例如:
Student(int age) { }编译器:
“你已经制定规则了,我不能偷偷增加一个空创建。”
否则:
Student s;会绕过你的设计。
六、特殊成员函数总结表
C++ 一个类默认有6个特殊函数:
| 函数 | 作用 | 什么时候自动生成 |
|---|---|---|
| 默认构造函数 | 创建空对象 | 没有任何构造函数时 |
| 析构函数 | 释放资源 | 通常自动生成 |
| 拷贝构造函数 | 复制对象 | 没有自己写时 |
| 拷贝赋值运算符 | 对象赋值 | 没有自己写时 |
| 移动构造函数 | 移动对象 | 满足条件时 |
| 移动赋值运算符 | 移动赋值 | 满足条件时 |
七、小学生记忆口诀
没有构造, 编译器造。 自己写了, 编译器跑。 想要空对象: class A { }; 可以。 写了: A(int x) 以后: A a; 不可以。八、和前面“对象创建过程”联系
创建:
Student s;过程:
第一步:
找到:
Student()第二步:
执行构造函数。
如果:
没有写构造函数:
编译器帮你生成。
如果:
你写了:
Student(int)那么:
默认构造函数不存在。
所以:
“自动生成默认构造函数”的核心判断方法:
看类里面有没有用户自己写的构造函数。
这也是 GESP/CSP C++ 面向对象部分非常喜欢考的知识点。
