C++重要知识点小结---2

C++知识点小结(趁热搬砖三年半的小码农) 2020年07月2日整理 c++最好用易用的新特性: auto/decltype https://blog.youkuaiyun.com/zyc2018/article/details/93591189 nullptr range-for using c++有哪些坑? 内存泄漏的解决方案: 智能指针 内存池 学习优秀的c++源码 Nginx Leveldb Envoy Folly Boost vector<int> month; int cnt=1; m... 阅读详情

C++重要知识点小结---2

C++重要知识点小结--1 :http://www.cnblogs.com/heyonggang/p/3246631.html

1.C++允许程序员声明一个不能有实例对象的类,这样的类惟一的用途是被继承。这种类成为抽象类。

一个抽象类至少具有一个纯虚函数。所谓纯虚函数是指被标明为不具体实现的虚成员函数。

如:

virtual void WithDrawal(float amount) = 0;  //纯虚函数

在WithDrawal()的声明之后的“=0”表明程序员将不定义该函数。该声明是为派生类而保留的位置。

一个抽象类不能有实例对象,即不能由该类抽象来制造一个对象。

纯虚函数是在基类中为子类保留的一个位置,以便子类用自己的实在函数定义来重载之。如果在基类中没有保留位置,则就没有重载。

纯虚函数是一个没有定义函数语句的基类虚函数,纯虚函数的值是0.派生类必须为每一个基类纯虚函数提供一个相应的函数定义。

2.派生类可以继承基类的所有公有和保护的数据成员和成员函数。

保护的访问权限对于派生类来说是公有的,而对于其它的对象来说是私有的。即使是派生类也不能访问基类的私有的数据成员和成员函数。

在派生类中允许重载基类的成员函数。如果基类中的函数是虚函数,当使用指针或引用访问对象时,将基于实际运行时指针所指向的对象类型来调用派生类的函数。

3.笔试,面试中常考的C++虚拟继承的知识点

第一种情况:         第二种情况:          第三种情况            第四种情况:
class a           class a              class a              class a
{              {                {                 {
    virtual void func();      virtual void func();       virtual void func();        virtual void func();
};              };                  char x;              char x;
class b:public virtual a   class b :public a           };                };
{              {                class b:public virtual a      class b:public a
    virtual void foo();        virtual void foo();     {                 {
};              };                  virtual void foo();        virtual void foo();
                               };                };

如果对这四种情况分别求sizeof(a),  sizeof(b)。结果是什么样的呢?下面是输出结果:(在vc6.0中运行)
第一种:4,12
第二种:4,4
第三种:8,16
第四种:8,8

可参考:http://blog.youkuaiyun.com/wangqiulin123456/article/details/8059536

想想这是为什么呢?

因为每个存在虚函数的类都要有一个4字节的指针指向自己的虚函数表,所以每种情况的类a所占的字节数应该是没有什么问题 的,那么类b的字节数怎么算呢?看“第一种”和“第三种”情况采用的是虚继承,那么这时候就要有这样的一个指针vptr_b_a,这个指针叫虚类指针,也 是四个字节;还要包括类a的字节数,所以类b的字节数就求出来了。而“第二种”和“第四种”情况则不包括vptr_b_a这个指针,这回应该木有问题了 吧。

复制代码
1 class a
2 {
3     virtual void func();
4 };
5 
6 class b:public a
7 {
8     void foo();
9 };
复制代码

此时:sizeof(a) = 4 , sizeof(b) = 4

复制代码
1 class a
2 {
3    void func();
4 };
5 
6 class b:public a
7 {
8     virtual void foo();
9 };
复制代码

此时:sizeof(a) = 1 , sizeof(b) = 4

复制代码
1 class a
2 {
3    void func();
4 };
5 
6 class b:public a
7 {
8     void foo();
9 };
复制代码

此时:sizeof(a) = 1 , sizeof(b) = 1

如下例:

 1 class A
 2 {
 3 };
 4 class A2
 5 {
 6 };
 7 class B : public A
 8 {
 9 };
10 class C : public virtual B
11 {
12 };
13 class D : public A , public A2
14 {
15 };
View Code

以上答案分别是1 , 1 , 4 , 1. 这说明:空类所占空间为1,单一继承的空类空间也为1,多重继承的空类空间还是1.但是虚继承涉及到虚表(虚指针),所以sizeof(C)的大小为4

4.多继承的构造顺序

构造对象的规则需要扩展以控制多重继承。构造函数按下列顺序被调用:

  1. 任何虚拟基类的构造函数按照它们被继承的顺序构造;
  2. 任何非虚拟基类的构造函数按照它们被继承的顺序构造;
  3. 任何成员对象的构造函数按照它们声明的顺序调用;
  4. 类自己的构造函数。

5.C++子类继承父类后子类的大小

复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class  A 
 4 {
 5 private:
 6  int a;
 7 };
 8 
 9 class B:public  A
10 {
11 private:
12  int b;
13 };
14 
15 int main()
16 {
17  cout<<sizeof(A)<<endl;
18  cout<<sizeof(B)<<endl;
19  return 0;
20 }
复制代码

刚开始我一想子类继承父类不会继承父类的私有变量,如此我认为结果为4,4(错误)。而事实上结果是4,8。也就是说子类把父类的私有变量也继承下来了,但是却无法访问,对于我这种菜鸟来说一下子没法转个弯来,后来看看资料焕然大悟,子类虽然无法直接访问父类的私有变量,但是子类继承的父类的函数却可以访问,不然的话如果只继承函数而不继承变量,哪么父类的函数岂不成了无米之炊了。所以必须把父类的所有变量都继承下来,这样既能保护父类的变量也能使用父类的函数。

6.继承的访问控制

继承分为公共继承、保护继承和私有继承。

在公共继承的类中,基类的每个成员在子类中保持同样的访问方式。即在基类中为public的成员,子类中可以访问,并据为public的;基类中为protected的成员,子类中也可访问之,并据为protected的;基类中为private的成员,在子类中不能访问之,这就像在应用程序中不能访问类中似有成员一样。

访问控制权限:

  • 私有继承时,基类中不管是公有的,还是保护的或者为私有的,一律在子类中变成私有成员。
  • 保护继承时,基类中公共和保护的成员在子类中变成保护的,而基类中私有的成员在子类中变成私有的。
  • 公共继承时,基类中为公共、保护和私有的成员在子类中仍保持为公共、保护和私有的。

如果不标明继承为公共还是保护或者私有,则默认的继承是私有的。

在继承关系中,基类的private成员不但对应用程序隐藏,甚至对派生类也隐藏。而基类的保护成员则只对应用程序隐藏,而对派生类则毫不隐瞒。

一个私有的或保护的派生类不是子类,因为非公共的派生类不能做基类能做的所有的事。

保护继承与私有继承类似,继承之后的类相对于基类来说是独立的;保护继承的类对象,在公开场合同样不能使用基类的成员。

派生类的构造函数必须激活所有基类的构造函数,并把相应的参数传递给它们。

也可参看:http://www.cnblogs.com/heyonggang/archive/2013/04/17/3026107.html

7.虚函数

C++虚函数用于实现动态绑定,或者说多态,默认的类方法是非虚函数,需要动态绑定的类方法,必需显式声明函数 virtual。

virtual函数必需在子类中再次声明,明确告诉子类有这个方法,否则编译时报错,getRange方法未声明的错误。

复制代码
复制代码
#include <iostream>
using namespace std;
class Range {
public:
    int width;
    int height;
    virtual float getRange();
    
    Range(int w, int h):width(w), height(h){};
    Range(){};
};

float Range::getRange() {
    return width * height;
}

class Square:public Range {
public:
    virtual float getRange();
    Square(){};
    Square(int w, int h):Range(w, h){};
};
float Square::getRange() {
    return width * width * 2;
}

class Circle:public Range {
public:
    virtual float getRange();
    Circle(){};
    Circle(int w, int h):Range(w, h){};
};
float Circle::getRange() {
    return 3.14 * width * width / 2;
}
int main(int argc, char* args[]) {
    Square s1(3, 4);
    Circle c1(2, 5);
    Range *r1 = &s1;
    cout << r1->getRange() << endl;
    Range *r2 = &c1;
    cout << r2->getRange() << endl;
    return 0;
}
复制代码
复制代码

输出结果为:

18

6.28

Square 和 Circle 都由一个 Range 指针指向,当调用 getRange方法,动态找到相应 Square 和 Circle 实例的getRange方法进行调用。

纯虚函数

C++的纯虚函数用于表示一个类不能被创建实例, 必需是子类覆盖该方法的定义后,方可新建类实例,格式是在虚函数后面添加 = 0。

假如上例中的Range只是一个初步表示区域的一个类,那么它的getRange()方法需要由子类实现才有效,表示为:

复制代码
virtual float getRange() = 0;
复制代码

此时不能再创建Range rt()实例,将会报错:

cannot declare variable ‘rt’ to be of abstract type ‘Range’
range2.cpp:3:13: note:   because the following virtual functions are pure within ‘Range’:

但我们仍然可以新建Range的指针,指向Circle或者是Square

一个有意思的问题:为什么析构函数要设置成虚函数

Range *r1 = new Circle(3, 4);

如果析构函数不是虚函数,则r1在释放内存时,则调用提Range的析构函数。

结果并不是想要的结果,我们想要的结果是调到Circle对象的析构函数。

如果析构函数是虚函数,有多态的支持,r1调用Circle对象的析构函数,Circle对象的析构函数默认调用父类Range的析构函数,保证Circle和Range对象的内容都得到清除。

避坑指南:RK3588视频编码与SRT推流实战中,我遇到的5个典型问题及解决方案 本文深度解析RK3588平台视频编码与SRT推流实战中的五个典型问题,包括MIPI摄像头内存对齐、多线程数据传递、FFmpeg时间戳设置、SRT连接参数调优及系统资源监控。提供具体解决方案和优化技巧,帮助开发者高效实现实时视频网络传输。 阅读详情

相关推荐

【UE5 C++开发指南】从零配置Visual Studio 2022开发环境

本文详细指导如何从零开始为UE5 C++开发配置Visual Studio 2022环境。文章强调了VS2022与UE5的深度兼容性,并逐步讲解了社区版下载、核心工作负载(如“使用C++的游戏开发”)与组件安装、界面优化、专属工具设置以及首个C++项目的创建与验证流程,帮助开发者高效搭建专业开发环境。

weixin_29016865的博客 392

c++报错invalid new-expression of abstract class type和cannot declare field "" to be of abstract type""

报错信息一invalid new-expression of abstract class type 基类纯虚函数 virtual double getArea()=0; 然而子类重写虚函数: virtual double getArea() const{ return PI*radius*radius; } 所以报错原因是纯虚函数没有加const,或者子类虚函数去...

diadestiny的博客 6432

从原理图到PCB:手把手教你绘制DRV8301驱动板(附完整代码与避坑指南)

本文详细介绍了如何从原理图设计到PCB布局,手把手教你绘制DRV8301驱动板,特别适用于FOC(磁场定向控制)系统开发。内容涵盖元器件选型、电源树架构设计、栅极驱动电路、PCB布局技巧、焊接调试及代码配置,并附有完整代码与常见问题避坑指南,帮助工程师快速掌握DRV8301驱动板的设计与优化。

weixin_33716941的博客 394

C++ 抽象类

抽象类是为了抽象和设计的目的而建立的,处于继承层次结构的上层。 具体类是能够建立对象的类。 抽象类的规定 (1)抽象类只能用作其他类的基类,不能建立抽象类对象。 (2)抽象类不能用作参数类型、函数返回类型或显式转换的类型。 (3)可以定义指向抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性。 #include using namespace std; const doub

3万+

Multisim14安装失败?手把手教你彻底清理残留文件(附专用卸载工具)

本文针对Multisim14安装失败问题,提供了一套从根源解决的完整方案。文章详细分析了安装失败的三大元凶——文件残留、注册表残留和隐藏组件,并手把手指导用户使用专用卸载工具进行标准化清理,再结合手动深度清理文件系统和注册表,最终实现彻底卸载和完美重装,有效解决Multisim14安装问题。

weixin_29179311的博客 317

从Transformer到Mamba:显著性检测领域的计算效率革命(Samba框架深度解析)

本文深入解析了Samba框架在显著性目标检测(Salient Object Detection)领域的创新应用,通过结合Mamba架构的优势,实现了计算效率的革命性提升。Samba框架采用显著性引导的Mamba模块(SGMB)和上下文感知上采样(CAU),有效解决了传统CNN和Transformer的局限性,同时在RGB-D等多模态任务中展现出卓越性能。

mmm90的博客 557

C++知识点小结

reference: 作者:大叔龙 链接:http://www.jianshu.com/p/e21d99638cf9 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。1.基础问答:容器、数据结构、排序算法什么得 2.然后一顿虚函数、虚函数表、纯虚函数、抽象类、析构函数、拷贝构造函数 3.操作数重载、STL、智能指针、内存问题1,你知道虚函数吗? 答案:实

code_caq的博客 1249

IDM更改下载路径的详细指南

Internet Download Manager(IDM)是一款功能全面的下载加速工具,它支持多种浏览器和协议,能够显著提升下载速度,同时提供断点续传、多线程下载等实用功能。IDM的用户界面简洁明了,操作便捷,使得用户能够轻松管理下载任务。此外,IDM还支持自动分类下载文件、定时下载等高级功能,进一步提升了用户的下载体验。通过本文的介绍,相信用户已经掌握了如何在IDM中更改下载路径的方法。这一功能不仅提升了下载效率和文件管理便捷性,还满足了用户的个性化需求。

nntxthml的博客 1762

C++中的引用知识点小结

文章目录引用的概念引用特性常引用使用场景引用和指针的区别 引用的概念 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。 比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"。那么这里的“铁牛”、“黑旋风”就称李逵的引用。 在程序中呢,引用的用法如下: 类型& 引用变量名(对象名) = 引用实体; 举个例子: void TestRef() { int a = 10; int& ra = a;//<====定义引

m0_56808122的博客 2043

Kafka 系列 —(17)Kafka 流式处理:Kafka Streams架构、使用场景、框架选择

本文介绍了KafkaStreams的架构特点、应用场景及与其他流处理框架的比较。KafkaStreams作为嵌入式分布式流处理库,其核心架构包含流处理器、任务、拓扑和本地状态存储,具备自动容错和伸缩能力。适用于实时监控、ETL、聚合、Join、物化视图等低延迟场景。与Flink、Spark相比,KafkaStreams适合简单架构和微服务,而Flink适合大规模处理,Spark更适合批处理。选择框架需根据具体场景需求,如微服务推荐KafkaStreams,大规模处理推荐Flink。

moton2017的博客 1631

【声呐技术】基于人工智能的拖曳阵声呐声学数据处理系统 SEA公司AI辅助拖曳阵系统

KraitSense是SEA公司开发的紧凑型被动拖曳阵声呐系统,核心传感器为KraitArray细线拖曳阵列。该系统专为小型舰艇、无人水面艇(USV)和无人潜航器(UUV)设计,通过人工智能与机器学习技术实现水下声学数据的自动化采集、处理与分类。系统与Mind Foundry公司开发的软件平台深度集成,形成端到端的智能反潜战(ASW)解决方案。

u012133341的博客 957

C++ 程序设计基本概念 知识点 小结

知识点包括:全局变量的二次赋值;计算转化为二进制后,数字中 1 的数量;用一个非循环表达式判断一个数是否是2的N次方;逻辑运算与位逻辑运算;printf 输入表达式的执行顺序;位运算判断输入参数是否为2的幂次;位运算两个数值的取平均与求和;无判断语句求取变量中较大存在;无中间量交换变量;C/C++关系。

稚枭天卓 2706

飞牛 NAS 部署 Hermes Agent 全指南:打造 24 小时在线、自我进化的 AI 智能体!

当大多数人还在把 AI 当聊天机器人使用时,我已经把它部署到了家里的飞牛 NAS 上,让它 24 小时在线工作、记忆我的习惯、自动执行任务,甚至还能不断学习新的技能。今天带你从零搭建这个真正属于自己的 AI Agent。🚀

XiaoqiangClub的博客 1222

C++PrimerPlus知识点小结

C++融合了3种不同的编程方式:C语言代表的过程性语言,C++在C语言基础上添加的类代表的面向对象语言(oop),C++模板支持的泛型编程。 C++11初始化方式 //大括号初始化,等号可以使用,也可以不使用 int emus{7}; int rheas={12}; //大括号内不包含任何东西,这种情况下变量将被初始化为零 int rocs={}; ...

qq_34921856的博客 1065

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

cpp知识点小结

cout 不会截断数据; 头文件:<iomanip> setw( )包括小数点,右对齐,字符串的空格也有效 ,只对下一个有效; cout . width ( ) ; setprecision ( )有效位数 ,一直有效; cout.precision ( ) ; setprecision(2) << setiosflags(iOS::fixed) 小数点位数 ; cout .setf ( ios::fixed | ios::showpoint) // 输出小...

weixin_54025765的博客 578

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C++基础知识点小结

C++基础知识点小结第一章 绪论(1)cout 输出流的对象(2)cin输入对象(3)endl 输出控制符/操控符(4)标识符(5)命名空间(namespace)(6)左值:(7)右值(8)c++赋值方式(整型和浮点型)(9)string字符串:第二章 引用与函数第三章 类的封装第四章 堆空间与深拷贝第五章 静态与友元第六章 继承与多态第七章 运算符重载第八章 模板与STL第九章 异常处理第十章 文件处理 C语言的缺点: 1.C类型检查机制相对较弱,这使得程序中的一些错误不能在编译时发现。 2.C本身

weixin_47946639的博客 513

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

C++小结

C++小结 一、构造函数和析构函数 对象的构造从类层次的最根处开始,在每一层中,首先调用基类的构造函数,然后调用成员对象的构造函数。析构则严格按照与构造相反的次序执行,该次序是唯一的,否则编译器将无法自动执行析构过程。 一个有趣的现象是,成员对象初始化的次序完全不受它们在初始化表中次序的影响,只由成员对象在类中声明的次序决定。这是因为类的声明是唯一的,而类的构造函数可以有多个,因此会有多...

大隐隐于野 366

C++:知识点小结

面相对象编程简称OOP,全称object oriented programming。就是以对象为核心的编程思想,它将现实世界中的事物抽象为程序中的“对象”,通过对象之间的交互来解决问题。核心及时将数据(属性)和操作数据的行为(方法)封装在一起,强调从“现实世界的实体”出发设计程序,而非单纯按照步骤(面向过程)解决问题。面向对象四大核心特征。

qq_58814618的博客 840

C++ 面向对象 知识点 小结

【摘要】 面向对象主要的知识点有,面向对象的基本概念,结构和类的区分,多态及各种构造函数。要求掌握 1.面向对象的基本原则(封装、继承、多态),面向对象的基本概念(类、对象、继承)。2.类和结构体在访问控制上的差异。3.成员变量在静态成员变量的4个特性、引用成员变量必须采用的初始化方式、静态常量成员变量的初始化特点以及成员变量在初始化列表初始化顺序上的特点。 4. string与stack的

稚枭天卓 3298

C++ 网络通信实践:cpp-httplib 与 websocketpp 入门指南,轻松实现 HTTP 与 WebSocket 交互

本文介绍 cpp - httplib 和 websocketpp 两个 C++ 库。前者轻量易用,支持 HTTP/HTTPS 客户端和服务端,适用于多种场景;后者遵循 RFC 6455,实现 WebSocket 全双工通信,帮助实现实时应用开发。

羑悻的博客. 3万+

C++字符串知识点小结

C++ 字符串 C++ 提供了一下两种类型的字符串表示形式: C风格字符串 C++引入的string 类类型 C风格字符串 C 风格的字符串起源于 C 语言,并在 C++ 中继续得到支持。字符串实际上是使用 null 字符 ‘\0’ 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。 下面的声明和初始化创建了一个 “Hello” 字符串。由于在数组的末尾...

怡红院 824

C++STL容器知识点小结

STL标准模板库 STL主要分为分为三类: algorithm(算法) - 对数据进行处理(解决问题) 步骤的有限集合 container(容器) - 用来管理一组数据元素 Iterator (迭代器) - 可遍历STL容器内全部或部分元素”的对象 容器和算法通过迭代器可以进行无缝地连接。在STL中几乎所有的代码都采用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。 STL 最早源于惠普实验室,早于C++存在,但是C++引入STL概念后,STL就成为C++的

半生瓜のblog 1079

C++重要知识点小结---1

C++重要知识点小结---1 1.C++中类与结构的唯一区别是:类(class)定义中默认情况下的成员是private的,而结构(struct)定义中默认情况下的成员是public的。 2. ::叫作用域区分符,指明一个函数属于哪个类或一个数据属于哪个类。::可以不跟类名,表示全局数据或全局函数(即非成员函数)。 3.类名加载成员函数名之前而不是加在函数的返回类型前。

1011
上一篇: C++ 虚拟继承
下一篇: 静态成员函数和非静态成员函数的区别?
大老鼠
博客等级 码龄15年 14粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值