c++类的特性探究(一)

咱们一起学C++ 第二百零三篇:之C++中protected关键字与私有继承的深入探究 大家好!C++作为一门强大的编程语言,有着丰富多样的特性,今天咱们来深入学习`protected`关键字以及私有继承相关的知识。希望通过这次学习,我们能更好地掌握C++的类继承机制,在编程之路上共同进步! 阅读详情

类的定义可以使用struct关键字或者class关键字,两者唯一的区别就是默认的访问权限。访问权限与类的访问控制说明符有关:

public:定义在public后面的成员可以在整个程序里面被访问

private:定义在private后面的成员只能在类内部被访问

struct Sales_data{
public:

//public成员,可在整个程序里面被访问
    //构造函数,用于创建对象时初始化数据成员
    Sales_data()=default;
    Sales_data(const string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n){}
    Sales_data(const string &s):bookNo(s){}
    Sales_data(istream&);
    //成员函数:关于sales_data对象的操作
    string isbn() const {return bookNo;}
    Sales_data & combine(const Sales_data&);
private:

//private成员,仅可在类内部被访问
    double avg_price()const{return units_sold?revenue/units_sold:0;};
    //数据成员:属于sales_data对象的属性
    string bookNo;
    unsigned units_sold=0;
    double revenue=0.0;
};

注:有些类成员可能定义在第一个说明符之外,那么此时如果使用struct关键字定义类,这些成员是public的,如果使用class关键字定义类,这些成员是private的。


友元:为了使得类的非成员接口函数能够访问类中的成员(包括公有私有),c++中引入友元一词,用以表示可以访问类的私有成员的友情函数。友元声明只能再类的内部,一般在顶部或者尾部,在函数前面加上friend关键字:

struct Sales_data{
friend Sales_data add(const Sales_data&,const Sales_data&);
friend ostream &print(ostream&,const Sales_data);
friend istream & read(istream&,Sales_data&);

public:
    //构造函数,用于创建对象时初始化数据成员
    Sales_data()=default;
    Sales_data(const string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n){}
    Sales_data(const string &s):bookNo(s){}
    Sales_data(istream&);


    //成员函数:关于sales_data对象的操作
    string isbn() const {return bookNo;}
    Sales_data & combine(const Sales_data&);
private:
    double avg_price()const{return units_sold?revenue/units_sold:0;};
    //数据成员:属于sales_data对象的属性
    string bookNo;
    unsigned units_sold=0;
    double revenue=0.0;
};

//这三个即为友元
Sales_data add(const Sales_data&,const Sales_data&);
ostream &print(ostream&,const Sales_data);
istream & read(istream&,Sales_data&);

友元函数虽然已经在类内部有过一次声明,但是在类的外部还需一次声明,通常将类的声明和友元函数的声明放在同一个头文件。

友元函数也可以直接在类内部定义,但是还是需要在类的外部再次进行声明以使得友元函数可见。

除了可以声明友元函数外,还可以声明友元类以及某一个类中的部分成员函数为友元函数。

class screen{

friend class WindowMgr;//声明class WindowMgr是class screen的友元类,class WindowMgr的成员函数可以访问class screen的非公有成员

friend void window_mgr::clear(int);//声明window_mgr的成员函数clear为screen的友元函数,可以访问screen的非公有成员。

}

如果要将某个类的成员函数作为一个类的友元,我们需要严格的组织程序结构,以window_mg的clear函数作为screen的友元为例:

1.首先定义window_mgr类,其中声明clear函数,但是不能定义它,因为它将要用到的screen还没有声明。

2.定义screen类,包括对于window_mgr的clear函数的友元声明

3.定义clear函数,此时可以使用screen。



友情小贴士:封装的益处

1.确保用户代码不会无意间破坏封装对象的状态

2.类的具体实现细节可以随时改变,而不用调整用户级代码


类的可变数据成员:

有时候我们希望只改变对象的某一个数据成员(即便这个对象是const对象),此时可以在数据成员的声明里面加入关键字mutable。

class Screen{
public:
    void some_member()const;//改变可变数据成员access_ctr,统计成员函数被访问次数
private:
    mutable size_t access_ctr=0;//可变数据成员
};
void Screen::some_member()const{
    ++access_ctr;
}


关于返回*this的成员函数

有些成员函数需要返回调用对象以进行下一步操作,此时成员函数应该返回对于调用对象的引用,这样才可保证所有的操作都是作用在调用对象上面。例如:

myScreen.move(4,0).set('#');//移动光标同时设定光标显示的字符

此时如果move函数返回对象的引用,那么紧随其后的set函数也是作用在myScreen上面;如果move函数返回对象,那么set函数将会作用在所返回的对象副本上,与myScreen无关。对于返回常量非常量引用可以使用函数重载的方法解决。对于函数体中对于常量对象和非常亮对象不同的操作可以将不同功能的代码独立成一个成员函数,由于类中的成员函数都是内联函数,所以不会带来函数调用的额外开销。


类的作用域:

当我们要使用类中的成员时,我们必须在这之前使用类名和作用运算符指定具体的类。在类的外部定义成员函数时,一般函数名前面会有类名,因此函数体和参数列表都可以使用类的成员,但是函数的返回类型是在函数名之前的,如果函数返回值类型需要用到类中的成员,那么必须也要使用作用域运算符指定具体的类,即便使用的是同一个类。

编译器处理类定义的两个阶段:

1.首先编译全体成员的声明(包括成员函数)

2.直到类全部可见之后才编译函数体(函数声明中返回类型、参数列表所用到的名字必须在声明以前已经出现过)

成员函数的块中使用符号时的名字查找规则:

1.首先在函数内部查找该名字

2.如果函数内部没有其定义或者声明,那么在类中查找该名字(成员函数之前或者之后出现的都可以,只要在类中声明)

3.如果在类中仍然未找到该名字,那么在类外的全局作用域中寻找该名字(必须在使用该名字之前有过定义)

注:类型别名比较特殊,类的内部不允许覆盖外部的类型别名。并且即便是在类内部,定义类型别名也必须先定义后使用

综合上述规则可理清楚程序中有关符号作用域的问题

57、C++ 类的深入探究与实践 本文深入探讨了C++类的重要特性,包括类的作用域、构造函数与析构函数、静态成员、友元函数等,并通过多个实际类的示例展示了如何使用这些特性进行编程实践。文章还详细解析了类的封装机制、成员访问控制、组合与继承等概念,并提供了多个类的完整实现,如复数类、分数类、时间类和日期类等,帮助读者掌握C++面向对象编程的核心技能。 阅读详情

相关推荐

C++新特性探究(一):nullptr

  nullptr 出现的目的是为了替代 NULL。在某种意义上来说,传统 C++ 会把 NULL、0 视为同一种东西,这取决于编译器如何定义 NULL,有些编译器会将 NULL 定义为 ((void*)0),有些则会直接将其定义为 0。   C++ 不允许直接将 void * 隐式转换到其他类型,但如果 NULL 被定义为 ((void*)0),那么当编译 char *ch = NULL; 时,NULL 只好被定义为 0。而这依然会产生问题,将导致了 C++ 中重载特性会发生混乱。 nullptr 是用.

小勇博客 944

Qt中的Sleep()和repaint()

<br />      Qt中要简单实现暂停一段时间,可以使用<windows.h>头文件中的函数Sleep(),但要注意调用格式是::Sleep(time_ms);,这个函数使用的较少,且不跨平台,更多的需要学习QTread类中的。<br />     最近在学习用模拟退火和遗传算法解决TSP问题,打算用Qt做界面动态显示城市旅行路线,要求不断刷新区域来显示一代代优化的路线,可以使用repaint()函数,该函数是QWidget类的一个方法。

ToddGong的学习之路 2044

C++中的类继承与多重继承机制探究

本文通过C++编程语言中类的继承和多重继承机制,详细介绍了如何在面向对象编程中构建层次化的类结构。通过对劳动者的基类和继承自劳动者的经理、科学家、工头等派生类的示例代码分析,展示了如何通过继承来复用代码和添加特定功能。同时,文章也探讨了类层次结构与组织结构图的不同,以及多重继承中的成员函数如何工作。

weixin_28949937的博客 392

Invalidate, Update, Repaint, Refresh的异同

Invalidate Invalidate方法通知Windows窗体的整个表面都应该重新绘制。最重要的是,Invalidate不会立即强制执行绘制操作。Windows只存储请求,只响应请求。 当前程序完全执行后,以及系统中没有其他未决事件后。Windows故意延迟绘制操作,因为这是最耗时的操作之一。有时因为这种延迟,只有在多次更改后才能绘制表单,从而避免多

lying_v的博客 636

QT update和repaint

qt 中更新界面和重绘的问题

Linux下OpenFire+Spark即时通讯环境搭建全攻略(含证书错误解决方案)

本文提供了一份详尽的Linux环境下OpenFire服务器与Spark客户端即时通讯系统的搭建与配置全攻略。内容涵盖从环境规划、服务端部署、数据库配置到客户端连接的全流程,并重点解决了Spark连接时常见的证书验证错误问题,为企业构建私有化、高可用的XMPP通讯平台提供了实战指导。

weixin_29251131的博客 164

c++函数特性一览

函数是代码快的集合,是编程语言里面不可缺少的部分,使用函数可以实现对数据和操作较好的封装,笔者有过一定的c语言函数基础,故而再次只讨论有关c++函数的一些特性。 重载:c++里面函数的一个重要特性便是函数重载,程序员可以定义多个名字相同但是形参列表不同的函数,在函数调用时,编译器会根据传入实参列表的形式选择正确的函数执行,这样一定程度上可以减轻程序员命名的负担,也使得函数调用更为简便。

Repaint_The_World的专栏 860

2023东华大学机试OJ进阶版1-81题

先排序。每次找两个最小的数,把其中一个置为两数之和,并累加这个和值,另一个数置为-1,然后再排序,重复操作,直到只剩下一个数。105。

m0_49263811的博客 2794

repaint()函数

repaint()这个方法是一个具有刷新页面效果的方法,如果你要页面进行重画就可以调用.一般都是在AWT的图形绘制当中调用的到.那么该方法具体的工作原来是怎么样的呢?看下面的结构流程图你就可以大概的了解了:     repaint()方法              |              |             V      AWT线程--->paint()方法-->图形绘制   |  

3621

别再傻傻分不清了!Anaconda和Miniconda到底选哪个?附保姆级安装与镜像源配置(Windows/Mac)

本文详细解析了Anaconda和Miniconda的核心差异,包括体积、预装内容、系统资源占用等关键维度,并提供了针对不同需求的决策框架。附有Windows和Mac双平台的详细安装与配置指南,帮助用户根据实际需求选择最适合的conda工具,提升开发效率。

weixin_30315723的博客 426

OpenBCI脑电数据处理实战:用MNE库从Raw对象到可视化分析全流程

本文提供了使用MNE-Python库处理OpenBCI脑电数据的完整实战指南。从通过BrainFlow库获取原始数据流、创建核心的Raw对象,到进行工频滤波、带通滤波等关键预处理步骤,最后实现时域信号、功率谱密度及地形图等多种专业可视化分析,手把手教你完成脑机接口数据处理的全流程。

gin88的博客 367

实战探究!C++ 20 标准都发布了哪些重要特性?

目前gcc 10.2可以支持部分C++20标准,编译的时候需要使用编译选项:-std=c++2a 待我升级编译器之后分章节详解主要特性的概念、示例。 敬请各位关注,干货马上到来 Constraints and concepts (约束和概念) 在类模板和函数模板编程中,主要用于对模板参数的结束和限制,这种约束和限制发生在编译期,编译错误不在那么晦涩难懂了。 在模板编程中,可以限制模板参数的类型或具用某种特性,如:可以限制为整型、数值型、bool型、或必须支持hash特性、或某个类的派生类型等。 在C++2

哦,原来你也在这里。 1万+

高德地图JS API私有化部署实战:从数据爬取到内网集成

本文详细介绍了高德地图JS API私有化部署的完整流程,涵盖从地图瓦片数据爬取、JS API离线化改造到内网项目集成的实战步骤。重点解决了在封闭内网环境中实现地图功能的核心难题,并提供了Vue.js项目中的具体集成代码与调试技巧,帮助开发者在离线环境下构建稳定可靠的地图应用。

weixin_29062255的博客 318

C++类的初步探究

第一篇博文,记录自己的成长         以前有过C/Java的编程经验,现在要学习一些C++的东西。不同语言的语法都是相通的,不同的地方在语言自己的特性。 有人说C++是C with class  再加上STL,粗略的看了一下,决定从C++的类开始学起。 开发环境:VS2017 1、建立一个最简单的自定义BookType类        首先是新建一个C++工程,这部分就不说了。类的声明...

qq_23594799的博客 221

流媒体协议-RTMP简介

与rtsp 不同,RTSP(Real-Time Streaming Protocol)是一个控制协议,负责控制媒体流的传输,但不传输媒体数据本身。RTSP 可以通过 TCP 或 UDP 传输 RTP 包来传输音视频数据。 RTMP(Real-Time Messaging Protocol)是一个综合性的协议,不仅可以传输音视频数据,还可以传输信令控制指令。RTMP 使用 TCP 作为传输协议,可以直接在 TCP 连接上传输音视频数据,也可以传输控制指令,实现了音视频流的实时传输和控制

xiaoshuaijinniu的博客 4550

踩坑实录:C#上位机YOLOv11从2FPS到45FPS,ONNX Runtime GPU加速全解析

算力迁移:将推理核心从CPU迁移至GPU(核心提速手段);内存复用:避免重复分配/释放内存,减少GC压力;维度固定:工业场景固定输入分辨率,关闭动态维度;资源限制:合理限制GPU/CPU/内存占用,避免资源耗尽;解耦设计:推理线程与UI线程解耦,避免跨线程问题。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 569

C++ | 深入浅出类的封装思想【图文案例,通俗易懂】

类和对象的封装思想核心在于什么?this指针的原理究竟是怎样的?本文来进行深入探讨和研究

做技术人 · 产优质博客 · 找好工作 3625

STM32硬件SPI配置为全双工模式下不要单独使用HAL_SPI_Transmit API及HAL_SPI_TransmitReceive改造方法

STM32 HAL库中SPI全双工模式使用问题总结:当配置为全双工模式时,单独使用HAL_SPI_Transmit会导致后续接收数据异常,原因是该API未处理接收数据。改造HAL_SPI_TransmitReceive使其支持单纯的发送/接收模式:当pTxData为NULL时只关心接收数据,pRxData为NULL时只关心发送数据,但仍会保持全双工通信。建议在全双工模式下统一使用改造后的HAL_SPI_TransmitReceive函数。

kevin1499的博客 900

C++一些特性的探究

在学习c++的过程中,也曾经学习java,就发现java有类的嵌套,而看的c++的书,从来没有哪个讲c++的类可以嵌套,于是就试了一下,看是否c++可以嵌套类(编译环境vc++6.0) 于是有了下面的代码: 1 #include <iostream> 2 using namespace std; 3 class A 4 { 5 public:...

diweng4066的博客 86

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

C++ 重要特性探究

C++部分特性进行总结

gma999的博客 1173

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【第48节】探究汇编使用特性:从基础到混合编程

函数返回时使用“ret 8”指令,这里的8表示参数占用的字节数,自动清理堆栈,减轻了调用者的负担,提高了代码的执行效率。汇编语言的这些特性为我们提供了丰富的编程手段,无论是优化性能、深入底层开发,还是进行混合编程,都能帮助我们更好地完成各种复杂的任务,在不同的编程场景中发挥出独特的价值,值得开发者们深入学习和探索。通过这样的方式,我们实现了C++与汇编语言的混合编程,充分发挥了两种语言的优势,既利用了汇编语言的高效性和对硬件的直接控制能力,又结合了C++的高级特性和便捷的编程方式。

攻城狮7号的博客 1835

解析C++的特性

C++的特性

2301_81739659的博客 1742

C++类使用上的几个问题(多态篇)

本文将会使你代入一个独特的视角看待C++的多态问题

2401_82410644的博客 685

【C++】详解类的--封装思想(让你丝滑的从C语言过度到C++!!)

从本文开始,我们就要重新认识一下C++中的类和对象了,本文我将总结我的心得,一步步解析从C语言的结构体struct到C++的类class,真正搞懂有关C++的面向对象的三大特征之一 ——封装

weixin_45031801的博客 6947

C++核心编程—类和对象,类的三大特性——封装、继承、多态

C++类和对象基础摘要 本文介绍了C++中类和对象的基本概念与应用。类是对现实世界对象的抽象,包含数据成员(属性)和成员函数(行为)。通过class关键字定义类,类中可以设置public、private、protected三种访问权限控制成员的可见性。对象是类的实例化,使用"类名 对象名"语法创建,通过"."或"->"访问成员。封装机制将属性和行为组合在一起,并通过访问权限控制外部访问,解决了C语言中属性和行为分离的问题。private和pr

阿标de杂货铺 2257
上一篇: 进程以及进程间关系
下一篇: linux内核综述
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值