目录
构造函数和析构函数,这两个函数将会被编译器自动调用,构造函数完成对象的初始化动作,析构函数在对象结束的时候完成清理工作。
注意:对象的初始化和清理工作是编译器强制我们要做的事情,即使自己不提供初始化操作和清理操作,编译器也会给你自动增加默认的操作,只是这个默认操作不会做任何事情。
构造函数:实例化对象的时候系统自动调用。? ? 析构函数:对象释放的时候自动调用。
构造函数函数名和类名相同,但没有返回值,也不能有void,但是可以有参数。
析构函数函数名是在类名前面加“~”组成,没有返回值,不能有void,不能有参数,不能重载。
案例:
Data.h:
class Data
{
private:
int num;
public:
void setNum(int data);
int getNum();
Data();
Data(int n);
~Data();
};
Data.cpp
#include "Data.h"
#include <iostream>
void Data::setNum(int data)
{
num = data;
}
int Data::getNum()
{
return num;
}
//构造函数(无参的构造)
Data::Data() {
std::cout << "无参的构造" << std::endl;
}
//构造函数(有参的构造)
Data::Data(int n) {
num = n;
std::cout << "有参的构造" << std::endl;
}
//析构函数
Data::~Data() {
std::cout << "析构函数" << std::endl;
}
main.cpp
#include <iostream>
#include "Data.h"
using namespace std;
int main() {
Data d;
}
运行结果:
1、实例化对象后系统自动调用构造函数
2、函数结束的时候 局部变量 d被释放,系统自动调用析构函数
注意:在同一作用域下,构造函数和析构函数顺序相反,简单说就是先执行的最后释放,后执行的最先释放。
按参数类型:分为有参和无参构造函数。
按类型分类:分为普通构造函数和拷贝构造函数。
无参构造的调用形式:
1、隐式调用
2、显示调用
?有参构造的调用形式:
1、隐式调用
//调用有参构造(隐式调用)
Data d(10);
cout << "dnum=" << d.getNum() << endl;
2、显示调用
//调用有参构造(显示调用)
Data d2 = Data(10);
cout << "d2num=" << d2.getNum() << endl;
运行结果:
3、匿名对象:(当前语句结束,匿名对象立即释放)
Data(40);
格式:类名(const 类名 &引用)
Data(const Data &d){
cout<<"拷贝构造函数"<<endl;
}
代码示例:
#include<iostream>
using namespace std;
class Data {
public:
int num;
Data();
Data(int data);
Data(const Data& ob);
~Data();
};
Data::Data()
{
cout << "这是无参构造" << endl;
}
Data::Data(int data)
{
num = data;
cout << "这是有参构造num=" <<num<< endl;
}
//拷贝构造
Data::Data(const Data& ob)
{
num = ob.num;
cout << "这是拷贝构造num=" << num<<endl;
}
Data::~Data()
{
cout << "析构函数num=" <<num << endl;
}
void Init() {
Data ob1(100);
cout << "ob1.num=" << ob1.num << endl;
Data ob2 = ob1;
cout << "ob2.num=" << ob2.num << endl;
}
int main() {
Init();
}
运行结果:
总结:
1、调用拷贝构造函数,如果用户不实现拷贝构造,系统将调用默认的拷贝构造。
2、默认的拷贝构造:单纯的整体赋值
3、如果用户实现了拷贝构造,系统将调用用户实现的拷贝构造,也就是上述代码Data::Data(int data)中的内容。
4、拷贝构造函数也有隐式调用和显示调用。
?注意:当旧对象初始化新对象才会调用拷贝构造函数。