本文代码仓库地址: gitee码云CSDN笔记仓库地址
构造函数调用原则【Class04】
// 对象的初始化和清理 -- 构造函数调用原则
#include <iostream>
using namespace std;
/*
* 默认情况下,C++编译器至少给一个类添加3个函数
* 1.默认构造函数【无参,函数体为空】
* 2.默认析构函数【无参,函数体为空】
* 3.默认拷贝构造函数,对属性进行值拷贝
*
* 构造函数调用规则:
* 1.如果用户定义有参构造函数,C++不在提供默认无参构造,但是会提供默认拷贝构造
* 2.如果用户定义拷贝构造函数,C++不会再提供其他构造函数
*/
// 如果用户定义有参构造函数,C++不在提供默认无参构造,但是会提供默认拷贝构造的情况
class person01_xy {
public:
int age = 0;
// 有参构造函数【可以鼠标放在上面会显示 还有一个重载】
person01_xy(int a) {
cout << "02--有参构造函数" << endl;
age = a;
}
// 析构函数
~person01_xy() {
cout << "04--析构函数" << endl;
}
};
// 如果用户定义拷贝构造函数,C++不会再提供其他构造函数
class person02_xy {
public:
int age = 0;
// 【可以鼠标放在上面就不会显示还有重载】
person02_xy(person02_xy &p) {
cout << "03--拷贝构造函数" << endl;
age = p.age;
}
// 析构函数【类被释放的时候调用】
~person02_xy() {
cout << "04--析构函数" << endl;
}
};
// 测试【用户定义有参构造函数,C++不在提供默认无参构造,但是会提供默认拷贝构造】
void fun01() {
// 这里直接声明 person01_xy,等于是调用它的无参构造函数即默认函数【会报错】
// person01_xy p1;
person01_xy p2(22);
// 这里是调用 person01_xy 的拷贝构造函数,类里面没有写,但是可以正常使用
person01_xy p3(p2);
cout << "p3的年龄 age = " << p3.age << endl;
}
// 【用户定义拷贝构造函数,C++不会再提供其他构造函数】
void fun02() {
// 这里直接声明 person01_xy,等于是调用它的无参构造函数即默认函数【会报错】
// person02_xy p1;
cout << "这里目前没有想到办法证明,知道有这么一回事就好了" << endl;
// 可以理解成为,无参构造 < 有参构造 < 拷贝构造
// 只声明有参构造,左侧的就被代替了,系统不会自动生成导致不可调用,右侧会自动生成可调用,只有拷贝构造的时候同理
}
int main() {
fun01();
cout << "------------------分界线------------------" << endl;
fun02();
cout << endl;
system("pause");
return 0;
}
浅拷贝与深拷贝【Class05】
// 对象的初始化和清理 -- 浅拷贝与深拷贝
#include <iostream>
using namespace std;
// 做浅拷贝的类
class person01_xy {
public:
string pName;
int* pAge = NULL;
// 无参构造区分先后顺序
person01_xy() {
cout << "01--person01_xy的无参构造函数" << endl;
}
person01_xy(string name, int age) {
cout << "02--person01_xy的两个参数构造函数" << endl;
pName = name;
// 在堆区开辟一个空间存放
pAge = new int(age);
}
~person01_xy() {
cout << "04--person01_xy的析构函数" << endl;
/* 加上下面的释放就会出现错误
if (pAge != NULL)
{
// 释放 pAge
delete pAge;
// 防止野指针出现
pAge = NULL;
}
*/
}
};
// 做深拷贝的类
class person02_xy {
public:
string pName;
int* pAge = NULL;
// 类对象作为类成员
person01_xy p1;
// 无参构造区分先后顺序
person02_xy() {
cout << "01--person02_xy的无参构造函数" << endl;
}
person02_xy(string name, int age) {
cout << "02--person02_xy的两个参数构造函数" << endl;
pName = name;
// 在堆区开辟一个空间存放
pAge = new int(age);
}
// 深拷贝构造函数
person02_xy(const person02_xy &p) {
cout << "03--person02_xy的拷贝构造函数" << endl;
pName = p.pName;
// 这里拷贝构造都会在堆区重新开辟一个空间存放,释放的时候就会释放自己对应的,不会出现重复释放
pAge = new int(*p.pAge);
}
~person02_xy() {
cout << "04--person02_xy的析构函数" << endl;
if (pAge != NULL)
{
// 释放 pAge
delete pAge;
// 防止野指针出现
pAge = NULL;
}
}
};
// 测试 浅拷贝的操作【就目前看来没有问题,但是我们在析构函数中释放age就会出现错误】
void fun01() {
// 这里调用系统生成的拷贝构造函数,进行浅拷贝
person01_xy p1("小印01", 22);
cout << "p1.pAge的地址:" << p1.pAge << endl;
// 这个系统的默认的浅拷贝,会完全拷贝p1的值,由于pAge是一个指针,拷贝过来的也是指针,所以它们就会值指向同一个地址
person01_xy p2(p1);
cout << "姓名 pName = " << p2.pName << " 年龄 age = " << *(p2.pAge) << endl;
cout << "p2.pAge的地址:" << p2.pAge << endl;
// p1 和 p2 中pAge的地址指向是同一个地址,析构执行了两次,如果这个时候在析构中释放pAge,就会出现相同的地址被重复释放报错
}
// 测试 深拷贝的操作
void fun02() {
person02_xy p1("小印02", 23);
cout << "p1.pAge的地址:" << p1.pAge << endl;
person02_xy p2(p1);
cout << "姓名 pName = " << p2.pName << " 年龄 age = " << *(p2.pAge) << endl;
cout << "p2.pAge的地址:" << p2.pAge << endl;
}
// 测试 类对象作为类成员 两个类的构造函数和析构函数执行的先后顺序的对比
void fun03() {
person02_xy p1;
}
int main() {
fun01();
cout << "------------------分界线------------------" << endl;
fun02();
cout << "------------------分界线------------------" << endl;
// 类对象作为类成员
// 手机类作为人类的成员变量的一部分,在调用构造函数的时候先调用手机类中的,调用析构函数的时候则会先调用人类中的
fun03();
cout << endl;
system("pause");
return 0;
}
静态成员【class06】
// 对象的初始化和清理 -- 静态成员
#include <iostream>
using namespace std;
class person01_xy {
public:
int a = 0;
/*
* 静态成员变量
* 所有对象共享一份数据
* 在编译阶段分配内存
* 类内声明,类外初始化
*/
static int b;
person01_xy() {
cout << "01--person01_xy的无参构造函数" << endl;
}
/*
* 静态成员函数
* 所有对象共享一个函数
* 静态成员函数只能访问静态成员变量
*/
// 不附带修改成员变量的静态函数
static void pFun01() {
cout << "person01_xy 中的静态成员函数 pFun01" << endl;
// 静态成员函数中使用非静态成员变量就会报错
// a = 111;
b = 222;
// cout << "pFun01 中打印的 a = " << a << endl;
cout << "pFun01 中打印的 b = " << b << endl;
}
// 附带修改成员变量的非静态函数
void pFun02() {
a = 333;
// b = 444;
cout << "pFun02 中打印的 a = " << a << endl;
// cout << "pFun02 中打印的 b = " << b << endl;
cout << "person01_xy 中的成员非静态函数 pFun02" << endl;
}
// 不附带修改成员变量的静态函数
static void pFun03() {
cout << "person01_xy 中的成员静态函数 pFun03" << endl;
}
// 不附带修改成员变量的非静态函数
void pFun04() {
cout << "person01_xy 中的成员非静态函数 pFun04" << endl;
}
// 打印静态成员变量
static void pFun05() {
cout << "此时的 b = " << b << endl;
cout << "person01_xy 中的成员静态函数 pFun05" << endl;
}
~person01_xy() {
cout << "04--person01_xy的析构函数" << endl;
}
};
void fun01() {
person01_xy p1;
p1.a = 666;
// 编译的时候会报错,也是因为静态的原因
// p1.b = 999;
// p1.pFun01();
p1.pFun02();
// 所有对象共享一个函数【不需要初始化也可以访问】
person01_xy::pFun03();
// 下面这样调用非静态成员函数就会报错
// person01_xy::pFun04();
cout << endl;
person01_xy p2;
p2.pFun03();
p2.pFun04();
// 编译出错
// p2.pFun05();
}
static void fun02() {
person01_xy p1;
// p1.a = 666;
// p1.b = 999;
// p1.pFun01();
// p1.pFun02();
p1.pFun03();
p1.pFun04();
// 编译出错
// p1.pFun05();
}
int main() {
fun01();
cout << "------------------分界线------------------" << endl;
fun02();
cout << endl;
system("pause");
return 0;
}
一点点笔记,以便以后翻阅。