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.mzph.cn/web/10444.shtml

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

相关文章

JavaScript 动态网页实例 —— 事件处理应用

前言 事件处理的应用很广泛。在事件处理的应用中,鼠标事件的应用是最常用到的。本章给出几个鼠标事件处理应用的示例,包括:页面预览、图像切换、点亮文本、鼠标跟随、鼠标感应和禁用鼠标按键。在这些示例中,有的可以直接拿来应用,有的则只提供了一种应用的方法,稍加拓展,…

示例十一、声音传感器

通过以下几个示例来具体展开学习,了解声音传感器原理及特性&#xff0c;学习声音传感器的应用&#xff08;干货版&#xff09;&#xff1a; 示例十一、声音传感器 ino文件源码&#xff1a; //Arduino C demo void setup() {Serial.begin(9600);pinMode(5, OUTPUT); }void loo…

【C/C++笔试练习】DNS设置文件、应用层、Dos攻击、DNS服务、DNS、子网划分、http状态、路由设置、TCP连接、HTTP状态码、剪花布条、客似云来

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;DNS设置文件&#xff08;2&#xff09;应用层&#xff08;3&#xff09;Dos攻击&#xff08;4&#xff09;DNS服务&#xff08;5&#xff09;DNS&#xff08;6&#xff09;子网划分&#xff08;7&#xff09;http状态&am…

docker01-简介和概述

什么是docker&#xff1f; 我们现在开发项目是在windows操作系统使用idea开发&#xff0c;本地windows操作系统上有我们项目所需的jdk&#xff0c;mysql&#xff0c;redis&#xff0c;tomcat等环境&#xff0c;如果我们想打包我们的项目到一个别的服务器上&#xff0c;在别的服…

SpringBoot实现图片验证码

引入依赖 <dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version> </dependency>代码实现 package com.qiangesoft.captcha.controller;import com.wf.captcha.*…

最少数量线段覆盖-华为OD

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、java代码五、测试用例 前言 本人最近再练习算法&#xff0c;所以会发布一些解题思路&#xff0c;希望大家多指教 一、题目描述 给定坐标轴上的一组线段&#xff0c;线段的起点和终点均为整数…

C++:类与对象—继承

类与对象—继承 一、继承是什么&#xff1f;二、继承定义三、基类和派生类对象赋值转换四、继承中的作用域五、派生类的默认成员函数六、继承与友元七、继承与静态成员八、复杂的菱形继承及菱形虚拟继承九、继承的总结和反思十、考察重点 一、继承是什么&#xff1f; 继承(inh…

Java的时间类

1. 日期类 1.1 第一代日期类 1) Date: 精确到毫秒&#xff0c;代表特定的瞬间 2) SimpleDateFormat: 格式和解析日期的类 SimpleDateFormat 格式化和解析日期的具体类。它允许进行格式化(日期-→>文本)、解析(文本->日期)和规范化. import java.text.ParseExce…

接口自动化测试很难掌握吗?

一. 什么是接口测试 接口测试是一种软件测试方法&#xff0c;用于验证不同软件组件之间的通信接口是否按预期工作。在接口测试中&#xff0c;测试人员会发送请求并检查接收到的响应&#xff0c;以确保接口在不同场景下都能正常工作。 就工具而言&#xff0c;常见的测试工具有…

AI+招聘:ATS招聘系统让HR简历筛选精准度达95%!

一提起招聘过程&#xff0c;许多HR就会想到那堆叠如山的简历、让人眼花缭乱的招聘网站以及琐碎繁复的手动数据录入。据统计&#xff0c;平均每位HR每年要处理数百甚至上千份简历&#xff0c;耗费大量精力在初级筛选和跟进上。   市场调查机构近日发布的一份报告显示&#xff…

【深度学习】YOLO源码中的mAP计算代码的理解笔记(大部分代码逐行+基础解释)

提示&#xff1a;本篇博客是在阅读了YOLO源码中的mAP计算方法的代码后加上官方解释以及自己的debug调试理解每一步是怎么操作的。由于是大部分代码进行了逐行解释&#xff0c;所以篇幅过长。 文章目录 前言一、输入格式处理1.1 转换公式二、init&#xff1a;初始化2.1 iouv2.2 …

【Leetcode每日一题】 综合练习 - 电话号码的字母组合(难度⭐⭐)(75)

1. 题目解析 题目链接&#xff1a;电话号码的字母组合 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 算法设计思路 在解决这类问题时&#xff0c;我们需要认识到每个位置上的数字对应的字符集合是相互独立的&#…

什么是翘尾因素

在有关CPI 的分析文章和新闻稿件中&#xff0c;经常会出现“翘尾因素”或“翘尾影响” 等词汇&#xff0c;这是分析同比价格指数变动幅度时所特有的概念。那么什么是“翘尾因素” 或“翘尾影响”呢&#xff1f; 一、什么是翘尾因素 “翘尾因素”是指上年价格上涨&#xff08;…

使用scrollIntoView滚动元素到可视区域

1. 实现效果 点击顶部标签栏&#xff0c;让对应的内容出现在可视区域&#xff1a; 2. scrollIntoView () scrollIntoView 是一个内置的 JavaScript 方法&#xff0c;用于将元素滚动到视口可见的位置。它通常用于用户界面中&#xff0c;以便用户能轻松看到特定的元素。此方…

perf 中的 cpu-cycles event 介绍

perf 中的 cpu-cycles event 介绍 cycles简介 cycles事件记录处理器核心执行的时钟周期数。每个时钟周期代表处理器内部时钟振荡器的一个周期。这个事件通常用于衡量处理器的执行速度&#xff0c;因为它直接反映了指令执行所需的时间。一个较高的cycles计数可能意味着代码执行…

2024版本idea集成SpringBoot + Ai 手写一个chatgpt 【推荐】

题目&#xff1a;SpringBoot OpenAi 在这里获取key和url&#xff1a;获取免费key base-url为这两个&#xff1a; 话不多说直接来&#xff01; 一、简介 Spring AI 是 AI 工程的应用框架。其目标是将 Spring 生态系统设计原则&#xff08;如可移植性和模块化设计&#xff…

暗区突围pc资格 暗区突围pc端测试资格获取

《暗区突围》的诞生&#xff0c;仿佛在游戏界投下了一枚深水炸弹&#xff0c;它不仅仅是射击游戏的新标杆&#xff0c;更是对玩家策略思维、生存直觉与团队协作能力的一次全面考验。在这个精心构建的虚拟战场中&#xff0c;每一次踏入暗区&#xff0c;都是对未知的探索&#xf…

【练习4】

1.两数之和 暴力&#xff1a; class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {int n nums.size();vector<int> res(2, -1); // 初始化结果为-1for (int i 0; i < n; i) {int temp nums[i];for (int j i 1; j <…

做视频号小店,怎么找达人合作?这里有详细讲解

大家好&#xff0c;我是电商笨笨熊 做视频号小店是没有自然流量的&#xff0c;这点刚入驻的新玩家还不清楚&#xff1b; 因此很多老电商玩家们还想着继续拿其他平台动销自然流的玩法去做视频号&#xff1b; 只能说这种方式在视频号是完全行不通的&#xff0c;当下想要推广售…

设计模式2——原则篇:依赖倒转原则、单一职责原则、合成|聚合复用原则、开放-封闭原则、迪米特法则、里氏代换原则

设计模式2——设计原则篇 目录 一、依赖倒转原则 二、单一职责原则&#xff08;SRP&#xff09; 三、合成|聚合复用原则&#xff08;CARP&#xff09; 四、开放-封闭原则 五、迪米特法则&#xff08;LoD&#xff09; 六、里氏代换原则 七、接口隔离原则 八、总结 一、依赖…