IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 06c++类和对象之对象的初始化和清理 -> 正文阅读

[C++知识库]06c++类和对象之对象的初始化和清理

1、构造函数和析构函数

#include<iostream>
using namespace std;

//1、构造函数  进行初始化操作
class person
{
	//1、构造函数
	//没有返回值,不用写void
	/*函数名和类名相同
	构造函数可以有参数,可以发生函数重载
	创建对象时,构造函数会自动调用,而且只会调用一次*/
public:
	person()
	{
		cout << "函数的调用" << endl;
	}

	//2、析构函数
	//没有返回值,不用写void
	//函数名和类名相同  在名称前加 ~
	//构造函数不可以有参数,不可以发生函数重载
	//对象在销毁前,会自动调用析构函数,而且只会调用一次
	~person()
	{
		cout << "析构函数函数的调用" << endl;
	}
};

//构造函数和析构函数都是必须有的实现,如果我们自己不提供,编译器会提供一个空实现的构造和析构
void test01()
{
	person p;//栈区	上的数据,test01执行完毕后,释放这个对象
}


int main()
{
	test01();

	system("pause");
	return 0;
}

2、构造函数的分类与调用

#include<iostream>
using namespace std;

//1、分类
//  按照有无参数分类  无参构造(默认构造)和 有参构造
//  按照类型分类  普通构造  拷贝构造
class person
{
public:
	person()
	{
		cout << "无参构造函数的调用" << endl;
	}
	person(int a)
	{
		age = a;
		cout << "有参构造函数的调用" << endl;
	}
	//拷贝构造函数
	person(const person& p)
	{
		//将传入的人身上所有属性,拷贝到我身上
		age = p.age;
		cout << "拷贝构造函数的调用" << endl;
	}
	~person()
	{
		cout << "析构函数的调用" << endl;
	}
	int age;

};

//调用
void test02()
{
	//1.括号法
	//person p1;//默认构造函数
	//person p2(10);//有参构造函数
	//person p3(p1);//拷贝构造函数
	
	//注意事项
	//调用默认构造函数时不要加()
	//因为下面这行代码,编译器会认为是一个函数的声明,不会认为在创建对象
	//person p();

	//2.显示法
	person p1;
	person p2 = person(10);//有参构造
	person p3 = person(p2);//拷贝构造

	//注意事项2.1:person(10);//匿名函数   特点:当前行执行结束后,系统会立即回收匿名对象
	//cout << "aaa" << endl;

	//2.2不要利用拷贝构造函数  初始化匿名对象   编译器会认为 person(p3) == person p3;即对象的声明
	//person(p3);

	/*cout << "p2的年龄:" << p2.age << endl;
	cout << "p3的年龄:" << p3.age << endl;*/

	//3.隐式转换法
	person p4 = 10;//相当于写了  person p4 = person(10);即有参构造函数
	person p5 = p4;
}

int main()
{
	test02();

	return 0;
}

3、拷贝构造函数的调用时机

#include<iostream>
using namespace std;

class person
{
public:
	person()
	{
		cout << "无参构造函数的调用" << endl;
	}
	person(int a)
	{
		age = a;
		cout << "有参构造函数的调用" << endl;
	}
	person(const person& p)
	{
		age = p.age;
		cout << "拷贝构造函数的调用" << endl;
	}
	~person()
	{
		cout << "析构构造函数的调用" << endl;
	}

	int age;

};

//1.使用一个已经创建完毕的对象来初始化一个新对象
void test03()
{
	person p1(10);
	person p2(p1);
}

//2.值传递的方式给函数参数传值
void dowork(person pp)//值传递   相当于隐式转换法  person pp = p3;
{

}

void test04()
{
	person p3;
	dowork(p3);//相当于隐式转换法  person pp = p3;
}

//3.值方式返回局部对象
person dowork2()
{
	person p6;
	cout << &p6 << endl;
	return p6;//局部变量在函数执行完后会自动释放,因此需要要一个变量来接受p6,即从test05;
}

void test05()
{
	person p = dowork2();//隐式转换法
	cout << &p << endl;
}
 
int main()
{
	test05();



	return 0;
}

4、构造函数的调用规则

#include<iostream>
using namespace std;

//构造函数的调用规则
//1、创建一个类,c++编译器会给每个类都添加至少3个函数
//默认构造函数(空实现)
//析构函数(空实现)
//拷贝构造(值拷贝) //注释原有的拷贝函数实现后即23行到27行,值依然可以复制到拷贝函数

//2、如果我们写了有参构造函数,编译器就不再提供默认构造,依然提供拷贝构造
//3、如果我们写了拷贝构造函数,编译器就不再提供其他构造函数
class person
{
public:
	//person()
	//{
	//	cout << "无参构造函数的调用" << endl;
	//}
	//person(int a)
	//{
	//	age = a;
	//	cout << "有参构造函数的调用" << endl;
	//}
	person(const person& p)
	{
		age = p.age;
		cout << "拷贝构造函数的调用" << endl;
	}
	~person()
	{
		cout << "析构构造函数的调用" << endl;
	}

	int age;

};

//void test001()
//{
//	person p1;
//	p1.age = 18;
//	person p2(p1);
//
//	cout << p2.age << endl;
//}


//void test002()
//{
//	person p1(28);
//	person p2(p1);
//	cout << p2.age << endl;
//}

void test003()
{
	person p1 = person(p1);
}
int main()
{
	//test001();
	//test002();
	test003();
	return 0;
}

5、浅拷贝和深拷贝

#include<iostream>
using namespace std;

class person
{
public:
	person()
	{
		cout << "无参构造函数的调用" << endl;
	}
	person(int a,int hight)
	{
		age = a;
		m_hight = new int(hight);
		cout << "有参构造函数的调用" << endl;
	}
	person(const person& p)
	{
		cout << "拷贝构造函数的调用" << endl;
		age = p.age;
		//m_hight = p.m_hight;//浅拷贝的就是编译器默认实现这行代码
		//深拷贝操作
		m_hight = new int(*p.m_hight);
	}
	~person()
	{
		//析构代码,将堆区开辟数据作释放的操作
		if (m_hight != NULL)
		{
			delete m_hight;
			m_hight = NULL;
		}
		cout << "析构构造函数的调用" << endl;
	}

	int age;
	int* m_hight;
};

void test01()
{
	person p1(18, 160);
	cout << p1.age << *p1.m_hight << endl;
	person p2(p1);
	cout << p2.age << *p2.m_hight << endl;
}

int main()
{
	test01();

	return 0;
}

6、初始化列表初始化值

#include<iostream>
using namespace std;

class person
{
public:
	//传统初始化操作
	//person(int a,int b,int c)
	//{
	//	m_a = a;
	//	m_b = b;
	//	m_c = c;
	//}

	//初始化列表初始化属性
	person(int a,int b,int c) :m_a(a), m_b(b), m_c(c)
	{

	}
	int m_a;
	int m_b;
	int m_c;
};


void test01()
{
	person p(30,20,10);

	cout << p.m_a << endl;
	cout << p.m_b << endl;
	cout << p.m_c << endl;
}

int main()
{
	test01();
	return 0;
}

7、类对象作为类成员

#include<iostream>
using namespace std;

class phone
{
public:
	phone(string pname)
	{
		cout << "phone" << endl;
		m_pname = pname;
	}
	~phone()
	{
		cout << "phone析构构造函数的调用" << endl;
	}
	string m_pname;
};

class person
{
public:
	person(string name, string pname) :m_name(name), m_phone(pname)
	{
		cout << "person" << endl;
	}
	~person()
	{
		cout << "person析构构造函数的调用" << endl;
	}
	string m_pname;
	string m_name;
	phone m_phone;
};
//当其他类对象作为本类成员,构造时候先构造其他类对象,再构造本身;析构的顺序与构造相反

void test()
{
	person p("张三", "华为");
	cout << p.m_name << "拿着" << p.m_phone.m_pname << endl;
}

int main()
{
	test();
	return 0;
}

8、静态成员变量

#include<iostream>
using namespace std;

class person
{
	//静态成员变量
public:
	//1、所有对象都共享一份数据
	//2、在编译阶段分配内存
	//3、类内声明,类外初始化操作
	static int m_a;

	//静态成员变量也是有访问权限的
private:
	static int m_b;
};

int person::m_a = 100;//3.2类外初始化操作
int person::m_b = 200;

void test()
{
	person p;
	cout << p.m_a << endl;

	person p2;
	p2.m_a = 200;

	cout << p.m_a << endl; //1、所有对象都共享一份数据;所以用p去访问时为200
}
void test02()
{
	//静态成员变量 不属于某个对象上,所有对象都共享同一份数据
	//因此静态成员变量有两种访问方式
	//1、通过对象进行访问
	//person p;
	//cout << p.m_a << endl;

	//2、通过类名进行访问
	cout << person::m_a << endl;

	//cout << person::m_b << endl;//静态成员变量也是有访问权限的
}
int main()
{
	//test();
	test02();
	return 0;
}

9、静态成员函数

#include<iostream>
using namespace std;


class person
{
public:
	//静态成员函数
	//1.所有对象共享同一个函数
	//2.静态成员函数只能访问静态成员变量
	static void func()
	{
		cout << "static void func的调用" << endl;

		m_a = 200; //静态成员函数可以访问静态成员变量
		//m_b = 300;//静态成员函数不可以访问非静态成员变量,因为非静态成员变量是某个对象有的,所以无法区分到底是哪个对象的
	}
	//静态成员变量
	static int m_a;//记得类内声明,类外初始化
	int m_b;//非静态成员变量

	//静态成员函数也是有访问权限的
private:
	static void func02()
	{
		cout << "static void func02的调用" << endl;
	}
};
int person::m_a = 100;

void test()
{
	//两种访问方式
	//1、通过对象访问
	person p;
	p.func();
	//2、通过类名访问  //所有对象共享同一个函数
	person::func();
	//person::func02(); 静态成员函数也是有访问权限的
}

int main()
{
	test();
	return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-03 12:51:42  更:2021-12-03 12:53:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:24:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码