#include <iostream>
#include <string>
using namespace std;
/****************************************************************************************
一、构造函数
1、构造函数作用:初始化对象成员。
2、函数名与类名相同;没有返回值,不用写void。
3、可以有参数、可以发生重载
4、在对象创立时,由编译器自动调用一次,无须手动调用。
二、析构函数
1、析构函数作用:释放对象占用的空间。
2、函数名:~类名;没有返回值,不用写void。
3、不可以有参数,不可以发生重载。
4、在对象销毁时,由编译器自动调用一次,无须手动调用。
三、构造函数的分类与调用
1、分类
a、按照参数分类:无参(默认)、有参。
b、按照类型分类:普通、拷贝构造
2、注意:
a、在创建类时,若无同时创建构造函数,编译器自动创建一个无参空构造函数;
b、在创建类时,同时创建了有参构造函数,无参构造函数须手动创建;
c、在创建类时,同时创建了拷贝构造函数,无参构造函数和有参构造函数都须手动创建。
四、拷贝构造函数调用机制
1、对象通过另一个对象进行初始化;
2、对象以值传递的方式传入函数参数;
3、对象以值传递的方式从函数返回。编译器优化,返回的是对象,未调用拷贝构造函数。
五、拷贝构造函数
1、拷贝构造函数的作用:使用同一类中已创建的对象来初始化一新对象。
2、默认拷贝构造函数:未自定义时由系统自动提供。拷贝规则:基本类型的成员变量,按
字节复制,类类型成员变量,调用其自身的拷贝构造函数。
3、类中存在指针成员变量,须自定义拷贝构造函数。
六、浅拷贝和深拷贝
1、浅拷贝:调用默认拷贝构造函数去赋值含有指针成员变量的对象,将会使两个对象的
指针成员变量指向的是同一块内存空间。
2、深拷贝:每个对象拥有自己的内存空间,须显示提供拷贝构造函数和赋值运算符。
****************************************************************************************/
class Person
{
public:
Person() // 无参构造函数
{
cout<<"这是无参构造函数调用"<<endl;
}
Person(string name, int age) // 有参构造函数
{
this->name = name;
this->age = age;
cout<<"这是有参构造函数调用"<<endl;
}
Person(const Person &p) // 拷贝构造函数
{
this->name = p.name;
this->age = p.age;
cout<<"这是拷贝构造函数调用"<<endl;
}
~Person() // 析构函数
{
cout<<"这是析构函数调用"<<endl;
}
void show()
{
cout<<"Name: "<<this->name<<endl;
cout<<"Age: "<<this->age<<endl;
}
private:
string name;
int age;
};
/******************************************************************************/
//1、对象通过另一个对象进行初始化;
void test01()
{
Person p1("Lisi", 29); // 调用有参构造函数进行对象初始化
// Person p1 = Person("Lisi", 29); // 调用有参构造函数进行对象初始化
Person p2 = p1; // 赋值初始化,调用拷贝构造函数
//Person p2(p1); // 复制初始化,调用拷贝构造函数
p2.show();
}
/******************************************************************************/
/******************************************************************************/
// 2、对象以值传递的方式传入函数参数
void Exampe(Person p)
{
cout<<"对象以值传递的方式传入函数参数"<<endl;
p.show();
}
void test02()
{
Person p1("Lisi", 29); // 调用有参构造函数进行对象初始化。
/*
调用函数Example的具体过程:
1、创建类型为Person临时变量p;
2、调用拷贝构造函数,将p1拷贝给p;
3、执行完函数Example,调用析构函数,销毁临时变量p。
1和2步可视为:Person p = p1
*/
Exampe(p1);
}
/******************************************************************************/
/******************************************************************************/
// 3、对象以值传递的方式从函数返回。
Person Exampe()
{
Person p1 = Person("Lisi", 29); // 调用有参构造函数进行对象初始化。
return p1;
}
void test03()
{
/*
调用函数Example的具体过程:
1、调用有参构造函数进行对象初始化;
2、开辟Person型匿名临时内存空间用于保存对象中数据;
3、执行完函数Example,销毁变量p1;
4、调用拷贝构造函数将匿名临时内存空间传递给p2
*/
Person p2 = Exampe();
//Exampe();
}
/******************************************************************************/
int main()
{
//test01();
//test02();
test03();
//cout<<"all"<<endl;
return 0;
}