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.hqwc.cn/news/687665.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解线程的两阶段终止模式:确保线程安全退出

序言 在多线程编程中&#xff0c;线程的安全退出是一个重要的问题。在实际应用中&#xff0c;我们经常需要确保线程在退出时能够完成必要的清理工作&#xff0c;同时避免因资源泄漏或状态不一致而导致的问题。线程的两阶段终止模式是一种解决这个问题的有效方法。本文将深入探…

推荐——通配符SSL证书该怎么申请?在哪里可以申请?

JoySSL是网盾安全基于全球可信顶级根创新推出的新一代https数字证书&#xff0c;也是目前为数不多的中国自主品牌SSL证书。JoySSL携手全球权威CA机构&#xff0c;全球多节点服务器验证签发&#xff0c;安全可信、完美兼容且更加稳定快速。JoySSL品牌提供通配符等证书所有适配范…

python之并发编程

python之并发编程 线程的创建方式线程的创建方式(方法包装)线程的创建方式(类包装)join()【让主线程等待子线程结束】守护线程【主线程结束&#xff0c;子线程就结束】 锁多线程操作同一个对象(未使用线程同步)多线程操作同一个对象(增加互斥锁&#xff0c;使用线程同步)死锁案…

SSIM(Structural Similarity),结构相似性及MATLAB实现

参考文献 Wang, Zhou; Bovik, A.C.; Sheikh, H.R.; Simoncelli, E.P. (2004-04-01). “Image quality assessment: from error visibility to structural similarity”. IEEE Transactions on Image Processing. 13 (4): 600–612. Bibcode:2004ITIP…13…600W. CiteSeerX 10.…

数字型隔离器ISO121x的用法

目录 概述 1 认识ISO121x 1.1 简介 1.2 特性 1.3 应用领域 2 ISO121x芯片结构 2.1 ISO1211引脚介绍 2.2 ISO1211的通用应用电路 2.3 Layout Example 3 应用范例 3.1 TI提供的评估板 3.2 评估板的原理图电路 概述 本文主要介绍ISO121x的相关特性&#xff0c;以及其…

9.spring-图书管理系统

文章目录 1.开发项目流程1.1开发开发1.2数据库的设计 2.MySQL数据库相关代码3.构造图书结构3.1用户登录3.2图书列表3.3图书添加3.4图书删除3.4.1批量删除 3.5图书查询(翻页) 4.页面展示4.1登录页面4.2列表页面4.3增加图书页面4.4修改图书信息页面 5.功能展示5.1增加图书信息5.2…

MySQL·表的内外连接

目录 表的内连和外连 内连接 案例1&#xff1a;显示SMITH的名字和部门名 外连接 左外连接 案例2&#xff1a; 查询所有学生的成绩&#xff0c;如果这个学生没有成绩&#xff0c;也要将学生的个人信息显示出来 右外连接 案例3&#xff1a;对stu表和exam表联合查询&#…

【Linux】什么是进程?

一个正在执行的程序&#xff0c;我们称之为进程。 然后我们来顺着一条线来思考。 操作系统底层是用C语言编写的&#xff0c;而我们的进程&#xff0c;它会有各种属性&#xff0c;那么各种属性就可以用一个结构体来对进程的各个属性进行描述&#xff0c;然后这个结构体里面&…

linux安装clamav病毒扫描与删除

ClamAV介绍 ClamAV是Linux操作系统一款免费的杀毒工具&#xff0c;通过命令执行病毒库升级、查找病毒和删除病毒。 安装ClamAV 方法一&#x1f4a1; Tips&#xff1a;在CentOS操作系统上安装ClamAV&#xff0c;请分别执行以下命令 yum install epel-release -y yum install cla…

Python 运筹优化11 BernoulliBandit 解读

说明 以广告点击的案例继续MultiArmed Bandit的学习。 内容 1 概要 样例假设存在5个广告&#xff0c;通过伯努利分布来模拟广告的点击可能。 adA BernoulliBandit(0.004) adB BernoulliBandit(0.016) adC BernoulliBandit(0.02) adD BernoulliBandit(0.028) adE Bern…

sipeed 的 MaixCam UART操作

发现问题 根据sipeed MaixCam官方文档 使用MaixVision会报错。 正确的接线 1&#xff0c;usb转ttl的RX和TX与sipeed MaixCam官方赠送的usb转接头反向连接&#xff0c;GND互相连接。 2&#xff0c;再用一根tpyc-c为其供电。 连接WiFi路由器 MaixCam液晶屏输入WiFi名称和密…

requestAnimationFrame请求动画帧

一、前言 在Web应用中&#xff0c;实现动画效果的方法比较多&#xff1a; CSS3&#xff1a;Transition&#xff08;过度&#xff09; / Animation&#xff08;动画&#xff09; HTML5&#xff1a;Canvas JavaScript&#xff1a;setInterval&#xff08;定时器&#xff09; /…