【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握

一、new和delete 堆区空间操作

1、new和delete操作基本类型的空间

new与C语言中mallocdelete和C语言中free 作用基本相同

 区别:

new 不用强制类型转换

new在申请空间的时候可以 初始化空间内容

2、 new申请基本类型的数组

 3、new和delete操作类的空间

 4、new申请操作对象数组

 二、静态成员

1、概念

类的对象 拥有独立的 普通成员数据。

static 修饰的成员 叫 静态成员。

class Data
{int a;//普通成员数据static int a;//静态成员数据static void func()//静态成员函数
{
}
};

2、静态成员数据

static修饰的静态成员 属于类而不是对象(所有对象 共享 一份 静态成员数据)。

实战案例:使用静态成员数据 统计对象的个数

#pragma warning(disable:4996)
#include<iostream>
using namespace std;
class Data
{
public:int mA;//普通成员数据static int count;//静态成员数据
public:Data(){count++;}Data(int a){mA = a;count++;}Data(const Data &ob){count++;}~Data(){count--;}
};
//类外初始化
int Data::count = 0;
void test()
{Data ob1;Data ob2(10);Data ob3 = ob2;cout << "对象个数:" << Data::count << endl;//3{Data ob4;Data ob5;cout << "对象个数:" << Data::count << endl;//5}cout << "对象个数:" << Data::count << endl;//3
}
int main(int argc, char* argv[])
{test();return 0;}

 3、静态成员函数

静态成员函数直接通过类名称访问

静态成员函数内 只能操作静态成员数据,因为普通成员数据还没有空间。

 三、单例模式

        单例模式可以保证结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。即单例模式的类 只能实例化 一个对象。

        核心:将构造函数私有化

#include <iostream>
using namespace std;
class SingleTon//单例模式
{
//构造私有化 防止实例化其他对象
private:SingleTon(){count=0;cout<<"构造"<<endl;}SingleTon(const SingleTon &ob){count=0;}~SingleTon(){cout<<"析够"<<endl;}
private://const防止p 在类内部 被修改指向static SingleTon * const p;//保存唯一的实例地址int count;//统计任务执行次数public:static SingleTon * getSingleTon(void)//获取唯一的实例地址{return p;}//用户自定义 任务函数void printString(char *str){count++;cout<<"当前第"<<count<<"次任务打印:"<<str<<endl;}
};
SingleTon *const SingleTon::p = new SingleTon;//创建唯一的实例int main(int argc, char *argv[])
{//获取单例的地址SingleTon *p1 =SingleTon::getSingleTon();//执行任务p1‐>printString("学历证明1");p1‐>printString("身份证明1");SingleTon *p2 =SingleTon::getSingleTon();p2‐>printString("学历证明2");p2‐>printString("身份证明2");
}

四、类的存储结构

        成员函数静态成员 是独立存储 是所有对象共享,不占类的空间。

五、this指针

         this是一个隐藏的指针,可以在类的成员函数中使用,它可以用来指向调用对象。当一个对象的成员函数被调用时,编译器会隐式地传递该对象的地址作为 this 指针。

        this 指针是一个特殊的指针,它指向当前对象的实例。每一个对象都能通过 this 指针来访问自己的地址。

        this可以完成链式操作 

六、const修饰成员函数 

        const 修饰成员函数为只读(该成员函数不允许对 成员数据 赋值mutable修饰的成员除外

七、友元

        预知识:将数据和方法封装在一起 加以权限区分 用户只能通过公共方法 操作私有数据。(封装 性)

        定义:一个函数或者类 作为了另一个类的友元 那么这个函数或类 就可以直接访问 另一个类的私 有数据。应用:友元 主要用在运算符重载上

        友元语法:friend关键字只出现在声明处,其他类、类成员函数、全局函数都可声明为友元,友元函数不是类的成员,不带 this指针友元函数可访问对象任意成员属性,包括私有属性。

        现实生活中也可以很好地理解:比如你的家,有客厅,有你的卧室,那么你的客厅是Public的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的闺蜜好基友进去。程序员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元

1、普通全局函数 作为类的友元

2、 类的某个成员函数 作为另一个类的友元

#pragma warning(disable:4996)
#include<iostream>
#include <string>
using namespace std;
class room;//向前声明,只能说明类名称
class Frind
{
public:void visiting01(Room& room);void visiting02(Room& room);
};
class Room
{friend void goodGay::visiting02(Room &room);
private:string bedroom;//实例化对象
public:string livingroom;
public:Room(string bedroom,string livingroom){this-> bedroom = bedroom;this-> livingroom = livingroom;}
};
void test()
{Room room("我的卧室", "我的客厅");Frind ob;ob.visiting01(room);ob.visiting02(room);
}
int main(int argc, char* argv[])
{test();return 0;}void Frind::visiting01(Room& room)
{cout << "李四访问到" << room.livingroom << endl;//cout<<"李四访问到"<<room.bedRoom<<endl;该成员函数不是类的友元,报错
}void Frind::visiting02(Room& room)
{cout << "好基友张三访问到" << room.livingroom << endl;cout << "好基友张三访问到" << room.bedroom << endl;}

 3、整个类作为 另一个类的友元

         这个类的所有成员函数 都可以访问另一个类的私有数据

#pragma warning(disable:4996)
#include<iostream>
#include <string>
using namespace std;
class room;//向前声明,只能说明类名称
class Frind
{
public:void visiting01(Room& room);void visiting02(Room& room);
};
class Room
{friend class Frind;
private:string bedroom;//实例化对象
public:string livingroom;
public:Room(string bedroom,string livingroom){this-> bedroom = bedroom;this-> livingroom = livingroom;}
};
void test()
{Room room("我的卧室", "我的客厅");Frind ob;ob.visiting01(room);ob.visiting02(room);
}
int main(int argc, char* argv[])
{test();return 0;}void Frind::visiting01(Room& room)
{cout << "李四访问到" << room.livingroom << endl;cout<<"李四访问到"<<room.bedRoom<<endl;
}void Frind::visiting02(Room& room)
{cout << "好基友张三访问到" << room.livingroom << endl;cout << "好基友张三访问到" << room.bedroom << endl;}

4、案例

(1)遥控器的类

#include <iostream>
using namespace std;
class TV;
class Remote//遥控器类
{
private:TV *p;
public:Remote(TV *p);void offOrOn(void);//开关void upVolume(void);//音量void downVolume(void);void upChannel(void);//频道void downChannel(void);void showTv(void);void setChannel(int channel);
};
class TV
{friend void Remote::setChannel(int channel);enum{OFF, ON};enum{minVol, maxVol=10};enum{minChan, maxChan=25};
private:int state;int volume;int channel;
public:TV(){state = OFF;volume = minVol;channel = minChan;}void offOrOn(void);void upVolume(void);void downVolume(void);void upChannel(void);void downChannel(void);void showTv(void);};
int main(int argc, char *argv[])
{//实例化一个电视机TV tv;Remote re(&tv);re.offOrOn();re.upVolume();re.upVolume();re.upVolume();re.setChannel(20);re.showTv();return 0;
}
void TV::offOrOn()
{state = (state==OFF?ON:OFF);return;
}
void TV::upVolume()
{if(volume == maxVol){cout<<"音量已经最大了"<<endl;return;
}volume++;return;
}void TV::downVolume()
{if(volume == minVol){cout<<"音量已经最小了"<<endl;return;
}volume‐‐;return;
}
void TV::upChannel()
{if(channel == maxChan){cout<<"频道已经最大了"<<endl;return;}channel++;return;
}void TV::downChannel()
{if(channel == minChan){cout<<"频道已经最小了"<<endl;return;}channel‐‐;return;
}
void TV::showTv()
{cout<<"当前电视机的状态:"<<(state==OFF?"关":"开")<<endl;cout<<"当前电视机的音量:"<<volume<<endl;cout<<"当前电视机的频道:"<<channel<<endl;
}
Remote::Remote(TV *p)
{this‐>p = p;
}
void Remote::offOrOn()
{p‐>offOrOn();
}void Remote::upVolume()
{p‐>upVolume();
}
void Remote::downVolume()
{p‐>downVolume();
}void Remote::upChannel()
{p‐>upChannel();
}void Remote::downChannel()
{p‐>downChannel();
}void Remote::showTv()
{p‐>showTv();
}
void Remote::setChannel(int channel)
{p‐>channel = channel;
}

(2)动态数组类

        根据数据大小动态增减空间。

array.h

#ifndef ARRAY_H
#define ARRAY_H
class Array
{
private:int *arr;//存放首元素地址int capacity;//容量int size;//大小
public:Array();Array(int capacity);Array(const Array &ob);~Array();int getCapacity() const;int getSize() const;void printArray(void);//插入尾部元素void pushBack(int elem);//删除尾部元素void popBack(void);int &at(int pos);
};#endif // ARRAY_H

array.cpp

#include "array.h"
#include<string.h>
#include<iostream>
using namespace std;
int Array::getCapacity() const
{return capacity;
}int Array::getSize() const
{return size;
}void Array::printArray()
{int i=0;for(i=0;i<size; i++){cout<<arr[i]<<" ";}cout<<endl;return;
}void Array::pushBack(int elem)
{//判断容器是否满if(size == capacity){//申请空间int *tmp = new int[2*capacity];//将就空间的内容 拷贝到新空间memcpy(tmp, arr, capacity*sizeof(int));//释放原有的空间delete [] arr;//更新arr的空间arr = tmp;//更新容量capacity = 2*capacity;}arr[size]=elem;size++;return;
}
void Array::popBack()
{if(size == 0){cout<<"容量为空"<<endl;}    else{size‐‐;}return;
}
int& Array::at(int pos)
{if(pos<0 || pos >=size){cout<<"访问违法内存"<<endl;exit(‐1);}return arr[pos];
}
Array::Array()
{capacity = 5;size = 0;arr = new int[capacity];//空间清0memset(arr, 0, sizeof(int)*capacity);
}
Array::Array(int capacity)
{this‐>capacity = capacity;size = 0;arr = new int[capacity];//空间清0memset(arr, 0, sizeof(int)*capacity);
}
Array::Array(const Array &ob)
{capacity = ob.capacity;size = ob.size;//深拷贝arr = new int[capacity];memcpy(arr, ob.arr, sizeof(int)*capacity);
}
Array::~Array()
{if(arr != NULL){delete [] arr;arr = NULL;}
}

main.c

#include <iostream>
#include "array.h"
using namespace std;
int main(int argc, char *argv[])
{Array ob;cout<<ob.getCapacity()<<" "<<ob.getSize()<<endl;ob.pushBack(10);ob.pushBack(20);ob.pushBack(30);ob.pushBack(40);ob.printArray();cout<<ob.getCapacity()<<" "<<ob.getSize()<<endl;ob.pushBack(50);ob.pushBack(60);ob.printArray();cout<<ob.getCapacity()<<" "<<ob.getSize()<<endl;ob.popBack();ob.popBack();ob.printArray();cout<<ob.getCapacity()<<" "<<ob.getSize()<<endl;cout<<"arr[2] = "<<ob.at(2)<<endl;ob.at(2) = 100;ob.printArray();return 0;
}

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

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

相关文章

为什么需要it企业知识库?it企业知识库能带来什么?

在企业运营过程中&#xff0c;会产生大量的经营数据、管理规范、资料和文档等数据&#xff0c;但这些数据的产生时间和空间碎片化&#xff0c;数据来源和结构多种多样&#xff0c;信息关系也较为复杂。 it企业知识库 正是因为这些问题的存在&#xff0c;导致了企业信息管理零散…

【word技巧】word页眉,如何禁止他人修改?

我们设置了页眉内容之后&#xff0c;不想其他人修改自己的页眉内容&#xff0c;我们可以设置加密的&#xff0c;设置方法如下&#xff1a; 先将页眉设置好&#xff0c;退出页眉设置之后&#xff0c;我们选择布局功能&#xff0c;点击分隔符 – 连续 设置完之后页面分为上下两节…

基于OpenAPI、freemarker动态生成swagger文档

前言 spring项目中可以使用springfox或者springdoc&#xff0c;通过写注解的方式生成swagger文档&#xff0c;下面介绍一种不写注解&#xff0c;动态生成swagger文档的方式&#xff0c;在某些场景会适用&#xff0c;例如接口是动态生成的&#xff0c;此时swagger就不能通过注解…

Qt中QFile、QByteArray QDataStream和QTextStream区别及示例

在Qt中&#xff0c;QFile、QByteArray、QDataStream和QTextStream是常用的文件和数据处理类。 主要功能和区别 QFile&#xff1a; QFile是用于读写文本和二进制文件以及资源的I/O设备。可以单独使用QFile&#xff0c;或者更方便地与QTextStream或QDataStream一起使用。 通常在…

Cookie和Session

前言扩展&#xff1a;笔者在之前学习前端扫盲阶段&#xff0c;写过一个简单易读的&#xff1a;表白墙项目&#xff0c;具体的前端代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta ht…

mac安装+配置python3环境

一、python3下载 官网下载 https://www.python.org/ 二、python3安装 打开下载好的.pkg文件一直继续确认即可。 三、验证是否安装成功 打开终端&#xff0c;输入python3&#xff0c;如果返回python对应的版本信息&#xff0c;则安装成功。 四、python配置 如果需要输入…

基于卷积优化优化的BP神经网络(分类应用) - 附代码

基于卷积优化优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于卷积优化优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.卷积优化优化BP神经网络3.1 BP神经网络参数设置3.2 卷积优化算法应用 4.测试结果…

Qt窗体设计的布局

本文介绍Qt窗体的布局。 Qt窗体的布局分为手动布局和自动布局&#xff0c;手动布局即靠手工排布各控件的位置。而自动布局则是根据选择的布局类型自动按此类型排布各控件的位置&#xff0c;使用起来比较方便&#xff0c;本文主要介绍Qt的自动布局。 1.垂直布局 垂直布局就是…

基于WebRTC构建的程序因虚拟内存不足导致闪退问题的排查以及解决办法的探究

目录 1、WebRTC简介 2、问题现象描述 3、将Windbg附加到目标进程上分析 3.1、Windbg没有附加到主程序进程上&#xff0c;没有感知到异常或中断 3.2、Windbg感知到了中断&#xff0c;中断在DebugBreak函数调用上 3.3、32位进程用户态虚拟地址和内核态虚拟地址的划分 …

义乌再次位列第一档!2022年跨境电商综试区评估结果揭晓!

义乌跨境电商综试区捷报频传&#xff0c;在商务部公布的“2022年跨境电子商务综合试验区评估”结果中&#xff0c;中国&#xff08;义乌&#xff09;跨境电子商务综合试验区&#xff08;以下简称&#xff1a;“跨境综试区”&#xff09;评估结果为成效明显&#xff0c;综合排名…

【C++技能树】Lambda表达式

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 文章目录 0. Lambda表达式简介1. Lambda表达式2. Lambda表达式语法 0. Lambda表达式简介 在C98及之前,想要对sort进行自定义排序,或者对自定义类…

uniapp实现登录组件之外区域置灰并引导登录

实现需求 每个页面需要根据用户是否登录决定是否显示登陆组件,登录组件半屏底部显示,登录组件之外区域置灰,功能按钮点击之后引导提示登录.页面效果如下: 实现思路说明 设置登录组件背景颜色为灰色,将页面分成登录区域(底部)和非登陆区域(上面灰色显示部分), 置灰区域添加…

腾讯共享WiFi贴项目推广员是怎么收益的?

腾讯共享WiFi贴项目是一种非常普遍的商业共享模式&#xff0c;它为用户提供了便携、高速的无线网络服务。然而&#xff0c;人们对于这种项目是否真的能让共享WiFi贴推广员挣到钱还存在疑问。 腾讯共享WiFi贴扫码项目的运作方式是这样的&#xff1a;推广员将WiFi贴二维码粘贴到商…

Qt扫盲-QImage 理论总结

QImage 理论总结 一、概述二、读写图像文件三、图像信息四、像素操作1. 32位2. 8位 五、图像格式六、图像转换 一、概述 QImage类提供了一个独立于硬件的图像表示&#xff0c;允许直接访问像素数据&#xff0c;并且可以用作绘画设备。Qt提供了四个类来处理图像数据&#xff1a…

ES挂载不上怎么处理?

全文搜索 EelasticSearch安装 Docker安装 docker run -d --name es7 -e ES_JAVA_POTS"-Xms256m -Xmx256m" -e "discovery.typesingle-node" -v /home/206/es7/data/:/usr/share/elasticsearch/data -p 9200:9200 -p 9300:9300 elasticsearch:7.14.0 …

VS的使用时遇到了basePath不能是相对路径的问题,如何处理?

使用VS&#xff0c;当你编译运行代码时出现以下的问题 解决方法 原因&#xff1a;文件库的路径存在问题&#xff0c;需要把相对路径改为绝对路径。 如何解决&#xff1a;去右键点击解决方案&#xff0c;选择属性-》调试-》命令中的参数被设置为相对路径。就可以解决以上的问题…

【代码随想录第48天】动态规划7

代码随想录第48天| 动态规划7 322. 零钱兑换279.完全平方数 322. 零钱兑换 LeetCode题目&#xff1a; 322. 零钱兑换 代码随想录&#xff1a;322. 零钱兑换 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计…

(十二)Python文件操作(I/O)

和其它编程语言一样&#xff0c;Python 也具有操作文件&#xff08;I/O&#xff09;的能力&#xff0c;比如打开文件、读取和追加数据、插入和删除数据、关闭文件、删除文件等。 除了提供文件操作基本的函数之外&#xff0c;Python 还提供了很多模块&#xff0c;例如 fileinpu…

优质可视化素材大放送,全部免费,承包你今年的大屏项目

做大屏的时候&#xff0c;是不是经常遇到没有素材用的情况&#xff0c;也不知道从哪里可以下载到免费又酷炫的素材&#xff01;帆软君这就给你准备好了&#xff01; 还记得我们之前安利的FVD帆软视觉素材平台吗&#xff1f;最近上新了一波模板和视觉素材&#xff0c;都是从实战…

Pytorch深度学习快速入门—LeNet简单介绍(附代码)

一、网络模型结构 LeNet是具有代表性的CNN&#xff0c;在1998年被提出&#xff0c;是进行手写数字识别的网络&#xff0c;是其他深度学习网络模型的基础。如下图所示&#xff0c;它具有连狙的卷积层和池化层&#xff0c;最后经全连接层输出结果。 二、各层参数详解 2.1 INPUT层…