01面向类的讲解

指针指向类成员使用

代码:

#include<iostream>
using namespace std;

class Test
{
public:
	void func() { cout << "call Test::func" << endl; }
	static void static_func();
	int ma;

	static int mb; //不依赖对象
};
void Test::static_func() { cout << "Test::static_func " << endl; }
int Test::mb;
int main()
{
	Test t1;
	Test* t2 = new Test();
	//int a= 10; int *p =&a; *p = 30;
	//无法从"int Test::* 转换为 int *;
	int Test::* p = &Test::ma;
	//*p = 20;//错误
	t1.*p = 20;
	cout << "t1.ma = " << t1.ma << endl; //通过ma来看
	t2->*p = 30;
	cout << "t2-->ma = " << t2->ma << endl; //通过ma来看

	int* p1 = &Test::mb;
	*p1 = 40;
	cout << Test::mb << endl;

	//指向成员方法的指针
	//无法转换 “初始化”: 无法从“void (__cdecl Test::* )(void)”转换为“void (__cdecl *)(void)” 
	void(Test:: * func)() = &Test::func;
	(t1.*func)();
	(t2->*func)(); //普通成员函数依赖对象

	//定义一个函数指针指向类的静态成员函数
	void(*pfunc)() = &Test::static_func;
	(*pfunc)();
	delete t2;
	return 0;
}

总结:针对类成员普通的指针需要指定对象

2、深浅拷贝

#include<iostream>
#include<string>
using namespace std;

class People
{
public:
	People(const char* _name) : name(new char[strlen(_name) + 1])
	{
		strcpy_s(name, strlen(_name) + 1, _name);
	}

	People(const People& other) :name(new char[strlen(other.name) + 1]) //开辟控件赋值的是深拷贝
	{
		strcpy_s(name, strlen(other.name) + 1, other.name);
	}

	//深拷贝
	People& operator =(const People& other)
	{
		name = new char[strlen(other.name) + 1];
		strcpy_s(name, strlen(other.name) + 1, other.name);
	}
	~People()
	{
		delete[] name;
		cout << "析构函数" << typeid(*this).name() << endl;
	}

	void print()
	{
		cout << name << endl;
	}

private:
	char* name;
};

int main()
{
	People a("shabi");
	People b(a);
	People c = b;
	c.print();
	b.print();
	a.print();
	return 0;
}

效果如下:
在这里插入图片描述

3、构造和析构函数

#include<iostream>
using namespace std;

#include<time.h>
//构造函数和析构函数的讲解
class SeqStack
{
public:
	/*void init(int size = 10)
	{
		_stack = new int[size];
		_top = -1;
		_size = size;
	}*/
	SeqStack(int size = 10) //可以重载,多个参数
	{
		_stack = new int[size];
		_top = -1;
		_size = size;
	}

	/*void release()
	{
		delete[] _stack;
		_stack = nullptr;
	}*/

	~SeqStack()
	{
		delete[] _stack;
		_stack = nullptr;
		cout << "析构函数" << endl;
	
	}

	void push(int val)
	{
		if (full())
		{
			resize();
		}
		_stack[++_top] = val;

	}
	void pop()
	{
		if (empty())
		{
			return;
		}
		--_top;
	}
	int top()
	{
		return _stack[_top];
	}

	bool empty()
	{
		if (_top == -1)return true;
		return false;
	}

	bool full() { return _top == _size - 1; }
private:
	int* _stack;
	int _size;//存储顺序栈的元素
	int _top; //指向栈顶的位置

	void resize()
	{
		int* tmp = new int[_size * 2];
		for (int i = 0; i < _size; i++)
		{
			tmp[i] = _stack[i];
			//memset(tmp,_stack,sizeof(int)*_size);realloc 内存的拷贝
		}
		delete[] _stack;
		_stack = tmp;
		tmp = nullptr;
		_size *= 2;
	}
};

int main()
{
	SeqStack s;

	for (int i = 0; i < 15; i++)
	{
		s.push(rand() % 100);
	}
	while (!s.empty())
	{
		cout << s.top() << " ";
		s.pop();
	}
	//s.release();//释放成员变量占用的外部堆内存
	return 0;
}

效果如下:
在这里插入图片描述

4、构造函数的初始化列表

#include<iostream>
using namespace std;
#include<string>

/*
构造函数的初始化列表

*/

//日期类
class CDate
{
public:
	CDate(int y, int m, int d) :_year(y), _month(m), _day(d) //自定义之后不会再产生默认的构造函数了
	{

	}

	void show()
	{
		cout << "_year " << _year << endl;
		cout << " _month" << _month << endl;
		cout << "_day" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;

};
class CGoods
{
public:
	CGoods(const char* n, int a, double p, int y, int m, int d) :_date(y, m, d) //初始化的列表功能
	{
		strcpy_s(_name, strlen(n) + 1, n);
		_amount = a;
		_price = p;
	}
	void show()
	{
		cout << "name : " << _name << endl;
		cout << "amount: " << _amount << endl;
		cout << "price: " << _price << endl;
	}
	CDate test()
	{
		return _date;
	}
private:

	char _name[20];
	int _amount;
	double _price; //初始化顺序的时候,先name按照先后哈
	/*
	Test(int data = 10):mb(data),ma(mb);
	private:
		int ma;
		int mb;先初始化ma然后是mb
	*/
	CDate _date; //成员对象 没有合适的默认构造函数 说明写了之后,默认的就没了
};

int main()
{
	CGoods c("张三", 12, 12, 1, 1, 1);
	c.show();
	c.test().show();
	return 0;
}


效果展示:
在这里插入图片描述

5、掌握类的各种成员方法以及区别


#include<iostream>
using namespace std;
#include<string>

/*
构造函数的初始化列表

*/

//日期类
class CDate
{
public:
	CDate(int y, int m, int d) :_year(y), _month(m), _day(d) //自定义之后不会再产生默认的构造函数了
	{

	}

	void show()
	{
		cout << "_year " << _year << endl;
		cout << " _month" << _month << endl;
		cout << "_day" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;

};
class CGoods
{
public:
	CGoods(const char* n, int a, double p, int y, int m, int d) :_date(y, m, d) //初始化的列表功能
	{
		strcpy_s(_name, strlen(n) + 1, n);
		_amount = a;
		_price = p;
		goods_numbr++;
	}
	void show() const //常用方法
	{
		cout << "name : " << _name << endl;
		cout << "amount: " << _amount << endl;
		cout << "price: " << _price << endl;
	}
	CDate test()
	{
		return _date;
	}

	int get_number()
	{
		cout << "商品的总数量是: "<<goods_numbr << endl;
		//cout<<name;这种错的,不能访普通成员的变量
		return 1;
	}
private:

	char _name[20];
	int _amount;
	double _price; //初始化顺序的时候,先name按照先后哈
	/*
	Test(int data = 10):mb(data),ma(mb);
	private:
		int ma;
		int mb;先初始化ma然后是mb
	*/
	CDate _date; //成员对象 没有合适的默认构造函数 说明写了之后,默认的就没了

	//记录商品的成员变量数量
	static int goods_numbr; //不属于对象属于类级别
};
int CGoods::goods_numbr = 0;

int main()
{
	CGoods c("商品1", 12, 12, 1, 1, 1);
	CGoods c1("商品2", 12, 12, 1, 1, 1);
	CGoods c2("商品3", 12, 12, 1, 1, 1);
	CGoods c3("商品4", 12, 12, 1, 1, 1);
	c.show();
	c.test().show();
	c.get_number();
	//统计商品的总数量
	return 0;
}


/*
总结:
static静态成员方法
1、属于类的作用域
2、用类名作用域来调用方法
*/

6、类和对象、this指针

C++:OOP对象 OOP编程 this指针
C++:实体的抽象类型
四大特性: 抽象,封装,继承,多态
三种:公有私有以及保护 ,属性一般私有,提供公有的方法访问属性

7、实际运用

#include<iostream>
#include<string>
using namespace std;


//类和对象代码实践应用
class String
{
public:
	String(const char* str = nullptr)
	{
		if (str != nullptr)
		{
			m_data = new char[strlen(str) + 1];

			strcpy_s(this->m_data, strlen(str) + 1, str);
		}
		else
		{
			m_data = nullptr;
		}
	}
	String(const String& other)
	{
		if (this != &other)
		{
			m_data = new char[strlen(other.m_data) + 1];
			strcpy_s(m_data, strlen(other.m_data) + 1, other.m_data);

		}
		else
		{
			m_data = new char[1];
			*m_data = '\0';
		}
		
	}

	~String(void)//析构函数
	{
		delete[]m_data;
	}
	String& operator =(const String& other)
	{
		if (this == &other)
		{
			return *this;
		}
		delete[] m_data;
		m_data = new char[strlen(other.m_data) + 1];
		strcpy_s(m_data, strlen(other.m_data) + 1, other.m_data);
		return *this;
	}
private:
	char* m_data;

};

int main()
{
	String str1;
	String str2("hello");
	String str3(str2);
	String str4 = str3 = str2;//调用赋值重载函数
}
//循环队列 memcpy realloc 不太合适
#include<iostream>
#include<time.h>
using namespace std;

class Queue
{
public:
	Queue(int size = 5)
	{
		_queue = new int[size];
		_front = _rear = 0;
		_size = size;
	}
	//Queue(const Queue&) = delete;
	//Queue& operator=(const Queue&) = delete;
	Queue(const Queue& src)
	{
		_size = src._size;
		_front = src._front;
		_rear = src._rear;
		_queue = new int[_size];
		for (int i = _front; i != _rear; i++)
		{
			_queue[i] = src._queue[i];
		}
	}

	Queue& operator = (const Queue& src)
	{
		if (this == &src)return *this;
		_size = src._size;
		_front = src._front;
		_rear = src._rear;
		_queue = new int[_size];
		for (int i = _front; i != _rear; i++)
		{
			_queue[i] = src._queue[i];
		}
		return *this;
	}
	~Queue()
	{
		delete[] _queue;
		_queue = nullptr;
	}

	void push(int val) //入队操作
	{
		if (full())
		{
			resize();
		}
		_queue[_rear] = val;
		_rear = (_rear + 1) % _size;
	}
	void pop()
	{
		if (empty())
		{
			return;
		}
		_front = (_front + 1) % _size;
	}

	int front()
	{
		return _queue[_front];
	}
	bool full() { return (_rear + 1) % _size == _front; }
	bool empty() { return _front == _rear; }


private:
	int* _queue;
	int _front;
	int _rear;
	int _size;

	void resize()
	{
		int* ptmp = new int[2 * _size];
		int index = 0;
		for (int i = _front; i != _rear; i = (i + 1) % _size)
		{
			ptmp[index++] = _queue[i];
		}
		delete[]_queue;
		_queue = ptmp;
		_front = 0;
		_rear = index;
		_size *= 2;
	}
};

int main()
{
	Queue queue;

	for (int i = 0; i < 20; i++)
	{
		queue.push(rand() % 100);
	}
	Queue queue1 = queue;//删掉了拷贝构造就不行了
	while (!queue1.empty())
	{
		cout << queue1.front() << " ";
		queue1.pop();
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/611757.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DDS Blockset Shapes Demo

此示例演示DDS模块集Blockset形状演示应用程序。Shapes Demo是一个常见的数据分发服务&#xff08;DDS&#xff09;应用程序&#xff0c;用于介绍DDS概念&#xff0c;你可以使用它发布和订阅以简单形状&#xff08;圆形、方形和三角形&#xff09;表示的主题&#xff0c;并观察…

如何设计测试用例

一、介绍 测试用例就是一个文档&#xff0c;描述输入、动作、或者时间和一个期望的结果&#xff0c;其目的是确定应用程序的某个特性是否正常的工作。 二、基本格式 用例的基本要素包括测试用例编号、测试标题、重要级别、测试输入、操作步骤、预期结果等。 用例编号&#…

适合年轻人的恋爱交友脱单软件有哪些?中国十大社交软件排行榜分享

交友始祖&#xff1a;Tinder 一直很受欢迎&#xff0c;可以向上扫给 super like (每日有一次免费机会)。如果双方互相 like&#xff0c;代表配对成功&#xff0c;就可以开始聊天。另外&#xff0c;每日有 10 个 top picks 供选择&#xff0c;你可以免费选一位 主力编外&#xf…

添加一个索引要投产,需要哪些步骤?

编程一生 致力于写大家都能看懂的、有深度的 技术文章 05/2024 01 开场白 亚马逊有个bar raiser文化。就是说新招来的人一定要超过之前入职人员的平均水平&#xff0c;宁缺毋滥。越来越多的公司在推行这种文化。在这种氛围下&#xff1a;“虽然我不懂&#xff0c;但是活儿是能出…

一文了解webpack和vite中Tree-Shaking

1、什么是Tree-Shaking 1.1 摇树优化&#xff08;Tree Shaking&#xff09;是Webpack中一种用于优化JavaScript代码的技术。它的目标是通过静态分析&#xff0c;从代码中剔除未被使用的模块&#xff0c;从而减少最终打包文件的大小。 1.2 Tree-shaking 它的名字来源于通过摇晃…

纯血鸿蒙APP实战开发——数字滚动动效实现

介绍 本示例主要介绍了数字滚动动效的实现方案。 该方案多用于数字刷新&#xff0c;例如页面刷新抢票数量等场景。 效果图预览 使用说明&#xff1a; 下拉页面刷新&#xff0c;数字进行刷新。 实现思路 通过双重ForEach循环分别横向、纵向渲染数字。 Row() {ForEach(this…

基于SSM的文化遗产的保护与旅游开发系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的文化遗产的保护与旅游开发系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;…

Java中包的概念package

Package Package:包 指明方法、类所处的包&#xff1b; 将类分配到不同的包中&#xff0c;方便管理&#xff1b; 用于指明文件中定义的类、接口等结构所在的包&#xff1b; 一个源文件只要一个包的声明语句&#xff0c;必须放到开头&#xff1b; 属于标识符&#xff0c;满足命…

Java类加载器介绍

在Java中&#xff0c;类加载器是一种动态加载类的机制&#xff0c;它负责在运行时查找、加载和链接类文件。当Java应用程序需要创建某个类的对象时&#xff0c;类加载器会在运行时查找该类对应的.class文件&#xff0c;并将其加载到Java虚拟机中。Java类加载器通常分为三层&…

《ESP8266通信指南》15-MQTT连接、订阅MQTT主题并打印消息(基于Lua|适合新手|非常简单)

往期 《ESP8266通信指南》14-连接WIFI&#xff08;基于Lua&#xff09;-CSDN博客 《ESP8266通信指南》13-Lua 简单入门&#xff08;打印数据&#xff09;-CSDN博客 《ESP8266通信指南》12-Lua 固件烧录-CSDN博客 《ESP8266通信指南》11-Lua开发环境配置-CSDN博客 《ESP826…

空间复杂度

前言 通过上一节的学习&#xff0c;我们知道了衡量一个算法是否高效的标准就是复杂度&#xff0c;我们已经学习了时间复杂度&#xff0c;那么本节我们就了解一下空间复杂度的相关知识&#xff0c;那么我们废话不多说&#xff0c;正式进入今天的学习 空间复杂度 空间复杂度也是…

Bugku Crypto 部分题目简单题解(三)

where is flag 5 下载打开附件 Gx8EAA8SCBIfHQARCxMUHwsAHRwRHh8BEQwaFBQfGwMYCBYRHx4SBRQdGR8HAQ0QFQ 看着像base64解码 尝试后发现&#xff0c;使用在线工具无法解密 编写脚本 import base64enc Gx8EAA8SCBIfHQARCxMUHwsAHRwRHh8BEQwaFBQfGwMYCBYRHx4SBRQdGR8HAQ0QFQ tex…

机器学习——6.模型训练案例: 预测儿童神经缺陷分类TD/ADHD

案例目的 有一份EXCEL标注数据&#xff0c;如下&#xff0c;训练出合适的模型来预测儿童神经缺陷分类。 参考文章&#xff1a;机器学习——5.案例: 乳腺癌预测-CSDN博客 代码逻辑步骤 读取数据训练集与测试集拆分数据标准化数据转化为Pytorch张量label维度转换定义模型定义损…

MySQL慢查询SQL优化

一、慢查询日志 描述&#xff1a;通过慢查询日志等定位那些执行效率较低的SQL语句 查看 # 慢查询是否开启 show variables like slow_query_log%; # 慢查询超时时间 show variables like long_query_time%;执行SQL 开启慢查询日志 set global slow_query_log ON;设置慢查…

Secure Transformer Inference Made Non-interactive

目录 1.概述2.Attention2.1 Matrix multiplication (ciphertext-plaintext).2.2 Matrix multiplication (ciphertext-ciphertext)2.3 Placement of bootstrapping3.SIMD密文压缩和解压缩4.SIMD槽折叠5.实验结果 1.概述 我们提出了NEXUS&#xff0c;这是第一个用于安全变压器推…

pdf编辑软件,四款软件让你轻松玩转PDF编辑!

在信息爆炸的当今时代&#xff0c;PDF格式文档因其跨平台、不易被篡改的特性而深受大家喜爱。然而&#xff0c;如何高效地编辑PDF文档却成为许多人的难题。今天&#xff0c;我将为大家推荐四款实用的PDF编辑软件&#xff0c;让你轻松玩转PDF编辑&#xff0c;告别繁琐操作&#…

【Linux】为什么有僵尸状态,什么是僵尸进程,造成危害以及如何避免“内存泄漏”问题详解

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

基于Springboot的校园竞赛管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园竞赛管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

HarmonyOS开发案例:【生活健康app之编写通用工具类】(5)

本节将介绍日志打印、时间换算等通用工具类的编写和使用&#xff0c;工具类可以简化应用代码编写和业务流程处理。 日志类 日志类Logger旨在提供一个全局的日志打印、日志管理的地方&#xff0c;既可以规范整个应用的日志打印&#xff0c;也方便日后对日志工具类进行修改&…

02.文件IO

文件描述符 表述打开的文件的 它是open函数的返回值&#xff0c;一个进程启动之后&#xff0c;会默认打开3个文件标识符 0标准输入&#xff0c;1标准输出&#xff0c;2标准错误 新的打开的文件返回文件描述符表中未使用过的最小的文件描述符 open函数 用来打开或者新建一个文件…
最新文章