C++面试指南——类常用知识点概念总结

news2024/9/21 12:46:46

构造函数

  1. 构造函数可以抛出异常,可以重载,如果在实例化时在类名后面加个括号,只是创建了一个匿名的对象。构造不能是虚函数,因为此时虚函数表还没有初始化。new对象会调解构造函数。
  2. 没有定义拷贝构造时,IDE会自动生成一个默认拷贝构造函数。当以值传递的类方式调用函数时,如果实参为对象,会调用拷贝构造函数。函数以值的方式返回对象时,vs会调用拷贝构造,g++则不会,默认拷贝属于浅拷贝
  3. 深拷贝:将原有对象的所有成员变量和持有内存都拷贝给新对象,并为新对象分配一块内存。原有对象和新对象所持有的动态内存是相互独立的。STL的容器都使用了深拷贝
  4. 浅拷贝:动态分配的内存时,指向其他数据的指针等,默认的拷贝构造函数就不能拷贝这些资源了

 注:当类有指针类型的成员变量,就需要深拷贝

静态成员变量

  1. static 成员变量的内存既不是在声明类时分配,也不是在创建对象时分配,而是在(类外)初始化时分配。没有在类外初始化的 static 成员变量不能使用。
  2. static 成员变量不占用对象的内存,而是在所有对象之外开辟内存,即使不创建对象也可以访问。所有的对象都共享这些静态成员变量。

静态成员函数

  1. 每个对象有各自的一份普通成员变量,但是静态成员变量只有一份,被所有对象所共享。静态成员函数不具体作用于某个对象。即便对象不存在,也可以访问类的静态成员。静态成员函数内部不能访问非静态成员变量,也不能调用非静态成员函数。
  2. 静态成员函数内部不能出现 this 指针

this指针

  • 其实在C++中。在定义类的成员函数时,是隐藏了一个参数的,该参数的定义为 const Name1* this,C++编译器根据不同的this指针执行不同对象的操作。

析构函数

  1. 没有参数,不能重载,不能抛出异常,内联。没有定义时,系统会默认生成一个析构函数。如果使用默认析构时,默认析构执行完成之后,会调用成员变量的析构,之后又调用派生类的析构,代码量会变大。会自动调用,也可以手工调用。
  2. 到析构时,虚函数表已初始化,可以把析构放在虚函数表里面来来调用。
  3. 当子类指针指向子类时,delete时基类和子类都会被释放。(  SubClass* pObj = new SubClass();delete pObj;)
  4. 当基类指针指向子类时,若析构函数是虚函数(加上virtual关键词),delete时基类和子类都会被释放。若析构函数不是虚函数delete时只释放基类,不释放子类,会造成内存泄漏问题。(BaseClass* pObj = new SubClass();delete pObj;)

虚函数

  1. 虚函数唯一用处就是构成多态:在运行时才可以明确调用对象,根据传入的对象类型来调用函数,例如当使用基类指针指向派生类对象时,能够调用派生类的成员函数,如果不是虚函数,调用的则是基类自己的成员函数。
  2. 构造函数不能是虚函数:虚函数的调用是通过虚函数表来查找,虚函数是对象构造后生成的。
  3. 内联函数不能是虚函数:inline属于是静态编译的。而虚函数是动态调用的,在编译器并不知道需要调用的是父 类还是子类的虚函数,所以不能够inline声明展开。
  4. 静态成员函数不能是虚函数:因为没有this指针。虚函数依靠虚函数函数指针和虚函数表来处理。虚函数指针在类的构造函数中创建生成,并且只能用this指针来访问它。对于静态成员函数,它没有this指针,所以无法访问虚函数. 
  5.  final :修饰虚函数,表示该虚函数不能再被重写;修饰类,该类不能被继承。
  6. override:override写在子类中,要求严格检查是否完成重写,如果没有完成重写就报错。

纯虚函数 

  •     纯虚函数是一个抽象的接口,没有默认的实现,用=0赋值。

多态

  1. 多态:是指同一个名字的事物能完成不同的功能,C++中可以分编译时多态(函数重载、运算符重载、按实参调用重载函数)和运行时多态。
  2. 运行时多态:虚函数让基类指针指向基类对象时就使用基类的成员,指向派生类对象时就使用派生类的成员。
  3. 多态的目的:可以通过基类指针对所有派生类(包括直接派生和间接派生)的成员变量和成员函数进行“全方位”的访问,尤其是成员函数。如果没有多态,只能访问成员变量。
  4. 构成多态:必须存在继承关系,继承关系中必须有同名的虚函数,并且它们是覆盖关系(函数原型相同),存在基类的指针,通过该指针调用虚函数。
  5. 协变:子类重写父类虚函数时,与父类虚函数返回值类型不同。

单继承

  1.  继承方式:公有继承public 仍为public ,protected为protected。保护继承public 仍为protected ,protected为protected。私有继承public 仍为private,protected为private。所有继承方式private都不能用。基类的 private 成员是能够被继承的,并且(成员变量)会占用派生类对象的内存,它只是在派生类中不可见。类的构造函数不能被继承。(基类对派生类隐藏基类的实现,以体现面向对象的封装性。)
  2. 派生类中的成员(包括成员变量和成员函数)和基类中的成员重名,那么就会遮蔽从基类继承过来的成员。所以基类成员函数和派生类成员函数不构成重载。
  3. 派生类对继承过来的成员变量要构造函数完成,但是大部分基类都有 private 属性的成员变量,它们在派生类中无法访问,更不能使用派生类的构造函数来初始化。所以在派生类的构造中调用基类的构造。
  4. 创建对象时,首先调用基类的构造,其次调用派生类的构造。派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的。( C->B->A,A的构造被隐显的调用两次,浪费cpu时间,所以禁止。)
  5. 析构函数不能被继承。在派生类的析构函数中不用显式地调用基类的析构函数,因为每个类只有一个析构函数。
  6. 创建派生类对象时,构造函数的执行顺序和继承顺序相同,即先执行基类构造函数,再执行派生类构造函数。而销毁派生类对象时,析构函数的执行顺序和继承顺序相反,即先执行派生类析构函数,再执行基类析构函数。

多继承

  1. 多继承时,派生类的构造函数中调用多个基类的构造函数。基类构造函数的调用顺序和和它们在派生类构造函数中出现的顺序无关,而是和声明派生类时基类出现的顺序相同。
  2. 多继承时,当两个或多个基类中有同名的成员时,会产生命名冲突,要在成员名字前面加上类名和域解析符::,以显式地指明到底使用哪个类的成员,消除二义性。

虚继承

  1.  为了解决多继承命名冲突和冗余数据问题,在派生类中只保留一份间接基类的成员,虚继承的目的是让某个类(虚基类)做出声明,承诺愿意共享它的基类。不论虚基类在继承体系中出现了多少次,在派生类中都只包含一份虚基类的成员。
  2. 虚派生只影响从指定了虚基类的派生类中进一步派生出来的类,它不会影响派生类本身。因为在虚继承的最终派生类中只保留了一份虚基类的成员,所以该成员可以被直接访问,不会产生二义性。此外,如果虚基类的成员只被一条派生路径覆盖,那么仍然可以直接访问这个被覆盖的成员。但是如果该成员被两条或多条路径覆盖了,那就不能直接访问了,此时必须指明该成员属于哪个类。
  3. 虚基类是由最终的派生类初始化,最终派生类的构造函数必须要调用虚基类的构造函数。对最终的派生类来说,虚基类是间接基类,而不是直接基类。这跟普通继承不同,在普通继承中,派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的。

类的内存

成员函数

  • 成员函数是不占用对象的内存空间的,只有成员变量占用对象的内存空间,在实例时,是按照类的成员变量所占用的总字节数申请内存(满足内存对齐)

虚函数

  1. 当一个类包括虚函数时,该类自动包含一个指向虚函数vptr指针,虚函数表中存放了指向该类中定义的所有虚函数的指针(函数指针),可以通过vptr快速访问到虚函数。
  2. 派生类没有重写基类的虚函数,没有继承基类的 vptr 指针,进行多态操作时,如果调用派生类的虚函数(与基类同名的虚函数),是不会发生多态行为的,调用的仍然是基类的虚函数。
  3. 派生类重写了基类的虚函数,编译器给重写的虚函数重新分配了内存空间,在进行多态操作时,如果调用派生类的虚函数,那就会发生多态行为,调用的就会是派生类的虚函数!
  4. 派生类重写了基类的部分虚函数,重写的部分是派生类。

内存

  1.  对象所占用的存储空间的大小等于各成员变量所占用的存储空间的大小之和(内存对齐)
  2. 当内存使用完之后,会使用虚拟内存,也就是往硬盘里面写,之后程序会被杀掉。

视频教程

地址:链接:https://pan.baidu.com/s/1W0cfUPxnf9c8egzMm1rBVA  提取码:jpy3 
 

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

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

相关文章

关于编译的重要概念总结

文章目录什么是GNU什么是GCC / Ggcc / g编译的四个阶段gcc和g的主要区别MinGW-w64C语言版本C 98C 11C 14C 17C 20Makefilecmake回想初学编程的时候,大部分人都是从C语言开始学起的,除了一些常见的语法和思想,一些基础知识常常被人们忽略&…

智能汽车进入3.0时代,双目立体视觉「打通」智驾与底盘

每一次软硬件技术更迭,都在重构智能化。 2016年7月,上汽集团与阿里巴巴合作开发的互联网汽车荣威RX5正式上市,这被视为中国乘用车市场首次规模化引入互联网生态,第一次在软件层面实现对传统燃油车的升级。几个月后,英特…

python机器学习数据建模与分析——数据预测与预测建模

文章目录前言一、预测建模1.1 预测建模涉及的方面:1.2 预测建模的几何理解1.3 预测模型参数估计的基本策略1.4 有监督学习算法与损失函数:1.5 参数解空间和搜索策略1.6 预测模型的评价1.6.1 模型误差的评价指标1.6.2 模型的图形化评价工具1.6.3 训练误差…

“绿菜单”2.0发布 数据中心液冷生态建设进入加速期

近年来,随着数字化社会对算力需求的不断增长,数据中心能耗与散热问题日益凸显。液冷作为更加高效、低能耗的制冷技术,逐渐成为了数据中心建设的热门选择。对此,产业上下游企业热情高涨,液冷产品与方案纷纷亮相&#xf…

【Java】数据类型与变量

一、java中的数据类型 Java中数据类型主要分为两类:基本数据类型和引用数据类型。 1.与c语言相同的数据类型 short,int,double,float均与c语言保持相同。 2.与c语言不同的数据类型 byte--字节类型 char--字符类型 java中,byte类型只占一个字节&#xff…

手写简易 Spring(二)

文章目录手写简易 Spring(二)1. 扩展 BeanFactory 接口2. 实现资源加载器,从 Spring.xml 解析和注册 Bean 对象1. 核心实现类 XmlBeanDefinitionReader3. 实现应用上下文,自动识别、资源加载、扩展机制1. 应用上下文2. 核心实现类…

虚幻图文笔记:Character Creator 4角色通过AutoSetup For Unreal Engine插件导入UE5.1的过程笔记

在UE5端安装AutoSetup For Unreal Engine插件 AutoSetup For Unreal Engine是Reallusion官方提供的免费插件,官方下载地址,下载到的是一个可执行文件,点击安装,记住安装的位置⬇ 看装完毕后会打开一个文件夹,这里就是对…

nginx线程池源码剖析

文章目录nginx线程池1. 问题2. 解决办法 nginx线程池3. 线程池实现模型4. 线程池实现核心组件5.源码实现测试代码main.c封装互斥锁&条件变量线程池实现nginx线程池 1. 问题 处理事件过程“阻塞”怎么办? 忙于漫长的 CPU 密集型处理 读取文件,但文…

HTTP vs HTTPS: 网络通信的加密之争、你真的知道它们的区别吗?

前言 欢迎来到今天的每日一题,每日一提。之前有聊到,TCP/IP协议四层模型。所以我们知道,那四层分别是:应用层、传输层、网络层和数据链路层。那么今天聊一聊应用层里面的一个小知识点,HTTP和HTTPS之间有什么区别&#…

亚马逊被人差评了怎么办?

第一种: 也是最简单的做法就是通过电话或者邮件联系留差评的买家,大致意思就是按照货值的2-3倍作为赔偿,能不能把差评给删了 赔偿一个普通产品2-3倍的价格比起找服务商删一个差评几百到一千不等可以说是绰绰有余了,碰到那种愿意…

AI 工具大全

文章目录ChatGPT 聊天绘画与图像PPTAdoble语音通话捷径指令视频音乐汇集 AI 工具,改变个人办公姿势。拥抱新时代的“通用人工智能”。利用 AI 工具来改造你学习和工作的流程。通过将 AI 嵌入生活和工作的方方面面,你不仅能够获得沉浸式的学习体验&#x…

线上问题:FeignClient循环依赖及源码分析

1 场景复现 依赖关系:虚线左侧为实现的类,虚线右侧为Spring的原生接口类或注解。 正常看,没有循环依赖,但是,实际运行时,异常信息:Is there an unresolvable circular reference? 明确告知&am…

Navidrome - 开源音乐服务器【打造属于自己的音乐播放器】「端口映射」随时随地想听就听

文章目录1. 前言2. Navidrome网站搭建2.1 Navidrome下载和安装2.1.1 安装并添加ffmpeg2.1.2下载并配置Navidrome2.1.3 添加Navidrome到系统服务2.2. Navidrome网页测试3. 本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置4. 公网访问测试5. 结语1. 前言…

十二、市场活动:修改

功能需求 ①、用户在市场活动主页面,选择要修改的市场活动,点击"修改"按钮,弹出修改市场活动的模态窗口; ②、用户在修改市场活动的模态窗口填写表单,点击"更新"按钮,完成修改市场活动的功能. ③、 *每次能且只能修改一条市场活动 ④、*所有者 动态的…

电脑组装教程分享!

案例:如何自己组装电脑? 【看到身边的小伙伴组装一台自己的电脑,我也想试试。但是我对电脑并不是很熟悉,不太了解具体的电脑组装步骤,求一份详细的教程!】 电脑已经成为我们日常生活中不可或缺的一部分&a…

Nginx用作 内网CDN / edge cache 服务

文章目录什么是CDN?为什么需要 内网CDN/edge cache?Nginx配置Edge Cache服务配置简单静态文件缓存服务配置缓存控制$upstream_cache_statusGzip压缩参考什么是CDN? 首先要明白什么是CDN? CDN英文全称Content Delivery Network,…

Springboot基础学习之(十七):通过Shiro实现用户得到登录认证和授权

前几篇文章讲解了关于信息安全的另一框架Spring security ,今天趁热打铁基础的了解以下shiro这一框架。 什么是shiro? Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应…

c++11 标准模板(STL)(std::stack)(二)

定义于头文件 <stack> template< class T, class Container std::deque<T> > class stack;std::stack 类是容器适配器&#xff0c;它给予程序员栈的功能——特别是 FILO &#xff08;先进后出&#xff09;数据结构。 该类模板表现为底层容器的包装…

线索二叉树(前序,中序,后序线索化以及遍历)

其实在这之前我想了很久&#xff0c;这个线索化二叉树我个人感觉是比实现二叉链表要难&#xff0c;很抽象的一个东西。好了&#xff0c;话先不多说&#xff0c;老规矩&#xff0c;先上代码&#xff1a; #pragma once #include<stdio.h> #include<stdlib.h> #inclu…

std::inner_product与std::accumulate初始值设置踩坑

std::inner_product函数可以用于计算两个序列的内积。在这个函数中&#xff0c;我们需要传递四个参数&#xff1a;两个源序列的起始迭代器、一个初始值和一个二元函数对象。 std::inner_product函数将对两个源序列中的每个元素进行乘法运算&#xff0c;并将结果累加到初始值中…