C++ 基础【07】

本文代码仓库地址: 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;
}

一点点笔记,以便以后翻阅。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小印丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值