1、构造函数
构造函数(也叫构造器),在对象创建的时候自动调用,一般用于完成对象的初始化工作
特点
函数名与类同名,无返回值(void都不能写),可以有参数,可以重载,可以有多个构造函数
一旦自定义了构造函数,必须用其中一个自定义的构造函数来初始化对象
注意
通过malloc分配的对象不会调用构造函数
在某些特定的情况下,编译器才会为类生成空的无参的构造函数
#include <iostream>
using namespace std;
struct Person {
int m_age;
// 必须用其中一个自定义构造函数初始化
Person() {
m_age = 0;
cout << "Person" << endl;
}
Person(int age) {
m_age = age;
cout << "Person::"<< m_age << endl;
}
};
void test5() {
Person person; // 调用Person
Person person1(); // 函数声明,函数名称person2,返回对象类型Person
Person person2(2); // 调用Person(int)
Person* p1 = new Person;
Person* p2 = new Person();
Person* p3 = new Person(4);
}
int main() {
/*Person person;
Person person1(10);*/
/*Person* p = new Person();*/
/*Person* p = (Person*)malloc(sizeof(Person));
free(p);*/
test5();
return 0;
}
默认情况下,成员变量的初始化
struct Person {
int m_age;
}
// 全局区(成员变量初始化未0)
Person g_p1;
int main() {
// 栈空间,成员变量默认不会初始化
Person p1;
// 堆空间
Person *p2 = new Person; // 不初始化成员变量
Person *p3 = new Person(); // 初始化为0
Person *p4 = new Person[3]; // 不初始化成员变量
Person *p5 = new Person[3](); // 3个person对象的成员变量初始化为0
Person *p6 = new Person[3]{}; // 3个person对象的成员变量初始化为0
}
如果自定义了构造函数,除了全局区,其他内存空间的成员变量默认都不会被初始化,需要开发人员手动初始化
2、析构函数(Destructor)
析构函数(也叫析构器),在对象销毁的时候自动调用,一般用于完成对象的清理工作
特点
函数名以~开头,与类同名,无返回值(void都不能写),无参,不可以重载,有且只有一个析构函数
注意
通过malloc分配的对象free的时候不会调用析构函数
构造函数、析构函数要声明为public,才能被外界正常使用
struct Car {
int num;
Car() {
cout << "Car :: Constructor" << endl;
}
~Car() {
cout << "~Car :: Desturctor" << endl;
}
};
struct Person {
int num;
Car *m_car;
Person() {
m_car = new Car();
cout << "Person :: Constructor" << endl;
}
~Person() {
delete m_car;
cout << "~Person :: Desturctor" << endl;
}
};
3、父类的构造函数
子类的构造函数默认会调用父类的无参构造函数
如果子类的构造函数显式地调用了父类的有参构造函数,就不会再去默认调用父类的无参构造函数
如果父类缺少无参构造函数,子类的构造函数必须显式调用父类的有参构造函数
继承体系下的构造函数示例:
struct Person {
int m_age;
Person(): Person(0) {
}
Person(int age): m_age(age) {
}
};
struct Student: Person {
int m_no;
Student(): Student(0, 0) {
}
Student(int age, int no): Person(age), m_no(no) {
}
};
构造、析构顺序
struct Person {
int m_age;
Person(int age) : m_age(age) {
cout << "Person Constructor" << endl;
}
~Person() {
cout << "Person destructor" << endl;
}
};
struct Student : Person {
int m_no;
Student(int age, int no): m_no(no), Person(age) {
// call Person
cout << "Student Constructor" << endl;
}
~Student() {
cout << "Student destructor" << endl;
// call ~Person
}
};
/*
调用顺序
Person()
Student()
~Student()
~Person()
*/