【面试题】C++综合面试题

2023-10-27

1,简述C++虚函数作用及底层实现原理

虚函数的作用是使基类指针指向派生类对象时,访问派生类的同名函数,实现动态联编。
原理:每个含有虚函数的派生类对象都有一个或多个(多继承)虚函数表指针,虚函数表指针指向了一个虚函数表,如果该类重写了基类的虚函数,则存放派生类的虚函数地址,如果没有重写,则存放基类的虚函数地址。

2,一个对象访问普通函数和虚函数哪个更快?

答案是不一定。这就要看这个函数是否构成多态了,若是构成多态,那在访问这个函数的时候还需要去虚函数表中找,这时就是访问普通函数更快了,若不构成多态,则访问虚函数更快。

3,在什么情况下,析构函数需要是虚函数?

这道题上一篇博客中有具体讲解,链接戳这里。
http://blog.csdn.net/chaseraod/article/details/75195352

4,内联函数、构造函数、静态成员函数可以是虚函数吗?

首先要知道,虚函数是针对对象而言,在运行时才进行动态联编的。
(1)内联函数不可以是虚函数,因为内联函数是在函数体中进行替换,没有自己的地址,虚表指针无法找到它。
(2)构造函数不 能是虚函数,因为调用虚函数需要虚函数表指针,而在执行构造函数之前是没有虚函数表指针的。
(3)静态成员函数不可以是虚函数,静态函数是属于类本身的,不属于对象本身,自然无法有自己的虚函数表指针。

5,构造函数中可以调用虚函数吗?

答案是可以的。只是可能和你预期想要的结果不同。
你认为以下代码会输出什么?

class Base
{
public:
    Base()
    {
        Fuction();
    }

    virtual void Fuction()
    {
        cout << "Base::Fuction" << endl;
    }
};

class A : public Base
{
public:
    A()
    {
        Fuction();
    }

    virtual void Fuction()
    {
        cout << "A::Fuction" << endl;
    }
};

int main()
{
    A a;
    system("pause");
    return 0;
}

来看运行结果
这里写图片描述

我们知道,函数的执行顺序是先调用基类的构造函数,再调用子类的构造函数。C++中规定:调用应用程序是正在构建或销毁的对象,所调用的函数是
构造函数或析构函数自身的类或其基类中的一个基类,但不是派生类中覆盖它的函数。

6,简述C++中虚继承的作用及底层实现原理?

作用:虚继承用于解决菱形继承的二义性和数据冗余问题。
底层实现原理:与编译器相关,一般通过虚基类 指针实现,即各对象中只保存一份父类的对象,多继承时通过虚基类指针引用该公共对象,从而避 免菱形继承中的二义性问题。

7,引用和指针有什么区别?

(1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。如:
int a=1;int *p=&a;
int a=1;int &b=a;
上面定义了一个整形变量和一个指针变量p,该指针变量指向a的存储单元,即p的值是a存储单元的地址。
而下面2句定义了一个整形变量a和这个整形a的引用b,事实上a和b是同一个东西,在内存占有同一个存储单元。
(2)可以有const指针,但是没有const引用;
(3)指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a是不合法的)
(4)指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化;
(5)指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不会再改变了。
(6)”sizeof引用”得到的是所指向的变量(对象)的大小,而”sizeof指针”得到的是指针本身的大小;
(7)指针和引用的自增(++)运算意义不一样;
(8)指针传参时形参是实参的一份临时拷贝,而引用传参改变的是实参本身,因此,引用传参不仅节约时间还节约空间。

8,const和define有什么区别?

(1) 编译器处理方式不同
  define宏是在预处理阶段展开。
  const常量是编译运行阶段使用。
(2) 类型和安全检查不同
  define宏没有类型,不做任何类型检查,仅仅是展开。
  const常量有具体的类型,在编译阶段会执行类型检查。
(3) 存储方式不同
  define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。(宏定义不分配内存,变量定义分配内存。)const常量会在内存中分配(可以是堆中也可以是栈中)。
(4)const 可以节省空间,避免不必要的内存分配。
(5) 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
(6) 宏替换只作替换,不做计算,不做表达式求解; 宏预编译时就替换了,程序运行时,并不分配内存。

9,枚举类型优缺点?

枚举常量不会占用对象的存储空间,它们在编译时被全部求值。枚举常量的缺点是:它的隐含数据类型是整数,其最大值有限,且不能表示浮点数

10,static关键字的作用有哪些?

C语言中:
1)在函数体内,一个被声明为静态的变量在这一函数被调用过程中维持其值不变(该变量存放在静态变量区)。

2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。注意,只有在定义了变量后才能使用。如果变量定义在使用之后,要用extern 声明。所以,一般全部变量都会在文件的最开始处定义。

3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。

linux中:
(1)设置变量的存储域,函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;

(2)限制变量的作用域,在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;

(3)限制函数的作用域,在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;

基于以上,C++对static做了扩展:
(4)在类中的static成员变量意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,其修改值为该类的其它所有实例所见;

(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量

11,C++中const关键字的作用?

Const的使用
1、定义常量
(1)const修饰变量,以下两种定义形式在本质上是一样的。它的含义是:const修饰的类型为TYPE的变量value是不可变的。
TYPE const ValueName = value;
const TYPE ValueName = value;

(2)将const改为外部连接,作用于扩大至全局,编译时会分配内存,并且可以不进行初始化,仅仅作为声明,编译器认为在程序其他地方进行了定义.

   extend const int ValueName = value; 

2、指针使用CONST
(1)指针本身是常量不可变
(char*) const pContent;
const (char*) pContent;

(2)指针所指向的内容是常量不可变
const (char) *pContent;
(char) const *pContent;

(3)两者都不可变
const char* const pContent;

(4)还有其中区别方法,沿着*号划一条线:
如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。

3、函数中使用CONST

(1)const修饰函数参数
a.传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)

void function(const int Var);

b.参数指针所指内容为常量不可变

void function(const char* Var);

c.参数指针本身为常量不可变(也无意义,因为char* Var也是形参)

void function(char* const Var);

d.参数为引用,为了增加效率同时防止修改。修饰引用参数时:

void function(const Class& Var); //引用参数在函数内不可以改变

void function(const TYPE& Var); //引用参数在函数内为常量不可变

这样的一个const引用传递和最普通的函数按值传递的效果是一模一样的,他禁止对引用的对象的一切修改,唯一不同的是按值传递会先建立一个类对象的副本,
然后传递过去,而它直接传递地址,所以这种传递比按值传递更有效.另外只有引用的const传递可以传递一个临时对象,因为临时对象都是const属性,
且是不可见的,他短时间存在一个局部域中,所以不能使用指针,只有引用的const传递能够捕捉到这个家伙.

(2)const 修饰函数返回值
const修饰函数返回值其实用的并不是很多,它的含义和const修饰普通变量以及指针的含义基本相同。
a.const int fun1() //这个其实无意义,因为参数返回本身就是赋值。
b. const int * fun2() //调用时 const int *pValue = fun2();
//我们可以把fun2()看作成一个变量,即指针内容不可变。
c.int* const fun3() //调用时 int * const pValue = fun2();
//我们可以把fun2()看作成一个变量,即指针本身不可变。

一般情况下,函数的返回值为某个对象时,如果将其声明为const时,多用于操作符的重载。通常,不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。原因如下:如果返回值为某个对象为const(const
A test = A 实例)或某个对象的引用为const(const A& test = A实例)
,则返回值具有const属性,则返回实例只能访问类A中的公有(保护)数据成员和const成员函数,并且不允许对其进行赋值操作,这在一般情况下很少用到。

4、类相关CONST

(1)const修饰成员变量
const修饰类的成员函数,表示成员常量,不能被修改,同时它只能在初始化列表中赋值。
class A
{

const int nValue; //成员常量不能被修改

A(int x): nValue(x) { } ; //只能在初始化列表中赋值
}

(2)const修饰成员函数
const修饰类的成员函数,则该成员函数不能修改类中任何非const成员函数。一般写在函数的最后来修饰。
class A
{

void function()const; //常成员函数, 它不改变对象的成员变量.

//也不能调用类中任何非const成员函数。
}

对于const类对象/指针/引用,只能调用类的const成员函数,因此,const修饰成员函数的最重要作用就是限制对于const对象的使用。

a. const成员函数不被允许修改它所在对象的任何一个数据成员。

b. const成员函数能够访问对象的const成员,而其他成员函数不可以。

(3)const修饰类对象/对象指针/对象引用
const修饰类对象表示该对象为常量对象,其中的任何成员都不能被修改。对于对象指针和对象引用也是一样。

const修饰的对象,该对象的任何非const成员函数都不能被调用,因为任何非const成员函数会有修改成员变量的企图。
例如:
class AAA
{
void func1();
void func2() const;
}
const AAA aObj;
aObj.func1(); ×
aObj.func2(); 正确

const AAA* aObj = new AAA();
aObj-> func1(); ×
aObj-> func2(); 正确

12,C++中包含哪几种强制类型转换,他们有什么区别和联系?

1.static_cast
最常用的类型转换符,在正常情况下的类型转换,如把int i 转换为 float f;
f = float(i); 或者 f =static_cast(i);

2.const_cast
用于去除const属性,把const类型的指针变为非const类型的指针,如const int* fun(int x, int
y){}
int* ptr = const_cast

class C
{
//.....C没有虚函数
}

class T{
//...
}

int main()
{
dynamin_cast<T*>(new C);//错误
}

修改后:

      class C  
       {  
       virtual void m();//C现在是多态  
       }  



       class T{  
       //...  
       }  



       int main()  
       {  
       dynamin_cast<T*>(new C);//正确

       }

4.reinterpret_cast
reinterpret为重新解释的意思,即为数据的二进制形式重新解释,但是不改变其值,如:

inti; 
      char* ptr = "hello freind!";

      i = reinterpret_cast<int>(ptr);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【面试题】C++综合面试题 的相关文章

随机推荐

  • 秋招面经汇总(算法工程师,计算机视觉工程师,深度学习工程师,机器学习工程师)

    前言 随着高通的正式offer下来 基本上秋招结束了 剩下的就是一些三方和合同处理的事情 我的秋招从8月开始准备 到10月末 后面有可能再随便考一下省考选调什么的 体验一下 背景是广东工业大学本硕 1 7月份在某公司的研究院实习 有一篇SC
  • flutter ios webview不能打开http地址

    参考 1 iOS添加信任 webview flutter 在使用过程中会iOS出现无法加载HTTP请求的情况 但是Flutter 却可以加载HTTP请求 这就与两个的框架有关了 Flutter是独立于UIKit框架的 解决方案就是在iOS
  • Sql Server 增加字段、修改字段、修改类型、修改默认值

    原文 Sql Server 增加字段 修改字段 修改类型 修改默认值 1 修改字段名 alter table 表名 rename column A to B 2 修改字段类型 alter table 表名 alter column 字段名
  • cv2,Image,Tensor图像shape中hw顺序

    经常忘记h和w的顺序 这次记录一下 图像为h 1000 w 1700 从结果可以看到 Image比较特殊 是w h cv2的resize中的dsize也是w h img Image open 001 png print img size w
  • 数据库系统概念复习

    第2章 关系模型介绍 zcy 2021 5 10 2 1 关系型数据库的结构 关系 relation 表 元组 tuple 行 属性 attribute 列 域 domin 对于关系的每个属性 都存在一个允许取值的集合 关系的所有属性的域都
  • 关于华为--公司概况

    关于华为 公司概况 华为技术有限公司成立于1988年 专门从事通信网络技术与产品的研究 开发 生产与销售 致力于为电信运营商提供固定网 移动网 数据通信网和增值业务领域的网络解决方案 是中国电信市场的主要供应商之一 并已成功进入全球电信市场
  • Python Tkinter Gui 常用组件介绍 基本使用

    Python Tkinter Gui 窗口图标 标签 输入 单复选 文件导入 按钮 日志 等常用组件 基本使用 文章目录 Python Tkinter Gui 窗口图标 标签 输入 单复选 文件导入 按钮 日志 等常用组件 基本使用 TOC
  • 三、伊森商城 快速开发 配置&测试微服务基本CRUD功能 p12

    目录 一 商品服务整合MyBatis Plus 1 导入依赖 上一章已经在common导入过 2 配置数据源 2 1 导入数据库的驱动 2 2 配置application yml 2 2 配置MyBatis Plus 2 2 1 使用 Ma
  • java上传图片到阿里云oss云存储中,返回url链接地址

    前言 最近要做一个门户网站 图片较多 所以要采用图片服务器 我这里采用的是阿里云的oss云存储 1 个数无限制 2 阿里云备份3 性能也不错 oss对于图片的处理 也有api 但是我这里上传的图片只需要加个水印 所以只需要在oss那边设置一
  • TextView设置android:textAllCaps="true"带来的问题

    刚刚碰到一个问题 记录一下
  • Ubuntu20.04安装英伟达驱动步骤

    先给电脑修改tty配置 保证黑屏后能打开tty 问题收录 Ubuntu14 04无法进入到tty1 6的解决办法 tty1到tty6 君的名字的博客 CSDN博客 关键 使电脑开机后出现grub引导界面 因为后面会出现开机黑屏的情况 所以需
  • Linux校验和

    校验和checksum程序可以生成文件的校验和 通过校验和即可检验文件的完整性 生成文件的MD5sum student myhost md5sum a 9f96ef92fe742165873c313662f1f2b8 a 以上生成了32位1
  • DAO层演练代码

    part 1 原始版 public class JDBCUtil 获取连接操作 return throws Exception public static Connection getConnection throws Exception
  • Android手机屏幕RTMP推流工具

    Android手机屏幕RTMP推流工具是基于ffmpeg opencv开发的C eclipse androidstudio 程序 是一款可以将安卓手机屏幕上的任何内容推送到任意一款rtmp服务器上的工具 不仅可以分享手机屏幕内容 还可以分享
  • 安装SQL server 提示重新启动计算机失败怎么解决?

    SQL server是微软推出的数据库管理系统 广泛使用于大型多处理器的服务器等多种平台 最近有用户在安装SQL server 2008程序是提示重新启动计算机失败问题 如图 相信很多用户都会选择重启电脑 但再次安装时也依然出现同样错误问题
  • BUUCTF-Reverse:xor(涉及异或脚本编写)

    xor一般指异或 异或 英文为exclusive OR 缩写成xor异或 eor 是一个数学运算符 题目地址 https buuoj cn challenges xor 用IDA载入 寻找main函数 F5打开伪C代码 int cdecl
  • 服务追踪-日志搜索

    为什么要使用微服务跟踪 它解决了什么问题 为什么要用 ELK 它解决了什么问题
  • 解决华擎J3455安装群晖后启动慢

    把华擎J3455BIOS升级到1 8版本 下载地址 华擎科技 gt J3455 ITX华擎超合金 Intel 四核处理器 J3455 高达 2 3 GHz 支持 DDR3 DDR3L 1866 SO DIMM 1 PCIe 2 0 x1 1
  • 解决git无法拉项目

    C Users 用户名 ssh 创建config文件 文件名就叫config 没有后缀名 内容 Host HostkeyAlgorithms ssh rsa PubkeyAcceptedKeyTypes ssh rsa
  • 【面试题】C++综合面试题

    1 简述C 虚函数作用及底层实现原理 虚函数的作用是使基类指针指向派生类对象时 访问派生类的同名函数 实现动态联编 原理 每个含有虚函数的派生类对象都有一个或多个 多继承 虚函数表指针 虚函数表指针指向了一个虚函数表 如果该类重写了基类的虚