1.介绍
构造函数是一种特殊的函数,通常在创建对象时自动调用,且只有一次。如果不手写,系统将会替你完成,只不过函数是一个空实现。如果手写会调用自定义的构造函数。构造函数必须与类名相同,而且不能有返回值,返回值类型不能写任何类型包括void。
而析构函数是在对象销毁前自动调用且一次,同样函数名与类名相同,不过前面要加~。
2.分类
构造函数分为三种,默认构造,传参构造和拷贝构造。
默认构造:形式简单,无需传参,但是只是一个命名,成员属性为空。
class Person {
public:
Person(int age) {
this->age = age;
}
int age;
};
int main(){
Person p1;
}
传参构造:需要传入一个或多个参数,将成员属性赋值。
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Person {
public:
Person(int age) {
this->age = age;
}
int age;
};
int main() {
Person p1(5);
}
拷贝构造:将一个已经实例化的对象的属性完全赋给另一个即将实例化的对象,传参需要用引用方法,为了不改变原对象,前面加const。具体为什么要使用引用方法而不是值传递,请见浅谈为什么使用拷贝构造时需要用引用方式传递参数
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Person {
public:
Person(int age) {
this->age = age;
}
Person(const Person& p1) {
this->age = p1.age;
}
int age;
};
int main() {
Person p1(5);
Person p2(p1);
}
3.显示法构造
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Person {
public:
Person(int age) {
this->age = age;
}
Person(const Person& p1) {
this->age = p1.age;
}
int age;
};
int main() {
Person p1 = Person(5);//传参构造
Person p2 = Person(p1);//拷贝构造
}
代码中的Person(5)和Person(p1)构造的是一个匿名对象,当前执行结束之后,匿名对象会被立即回收。注意:不要使用拷贝构造函数初始化匿名对象,如:Person(p2),含义是用p2这个实例化的对象初始化一个匿名对象,对编译器来叔,这只是一个对象的定义声明,会报错重定义。
4.构造函数调用规则
1.每创建一个类的时候,系统自动生成三个函数,分别是默认构造函数,默认析构函数和拷贝构造函数,前两个不自定义的时候全是空实现。
2.当自定义传参构造之后,编译器将不会提供无参构造(即不能使用Person p1这样去实例化一个对象,必须传参),但依然提供拷贝构造。如果自定义了拷贝构造,编译器将不会提供不同构造(即只能使用拷贝构造)