【C++ 面试 - 面向对象】每日 3 题(六)

news2024/11/26 12:19:59

✍个人博客:Pandaconda-CSDN博客

📣专栏地址:http://t.csdnimg.cn/fYaBd

📚专栏简介:在这个专栏中,我将会分享 C++ 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

16. 什么是 虚拟继承?

由于 C++ 支持多继承,除了 public、protected 和 private 三种继承方式外,还支持虚拟(virtual)继承,举个例子:

#include <iostream>
using namespace std;

class A{}
class B : virtual public A{};
class C : virtual public A{};
class D : public B, public C{};

int main()
{
    cout << "sizeof(A):" << sizeof A <<endl; // 1,空对象,只有一个占位
    cout << "sizeof(B):" << sizeof B <<endl; // 4,一个bptr指针,省去占位,不需要对齐
    cout << "sizeof(C):" << sizeof C <<endl; // 4,一个bptr指针,省去占位,不需要对齐
    cout << "sizeof(D):" << sizeof D <<endl; // 8,两个bptr,省去占位,不需要对齐
}

上述代码所体现的关系是,B 和 C 虚拟继承 A,D 又公有继承 B 和 C,这种方式是一种菱形继承或者钻石继承,可以用如下图来表示:

  

  

虚拟继承的情况下,无论基类被继承多少次,只会存在一个实体。虚拟继承基类的子类中,子类会增加某种形式的指针,或者指向虚基类子对象,或者指向一个相关的表格;表格中存放的不是虚基类子对象的地址,就是其偏移量,此类指针被称为 bptr,如上图所示。如果既存在 vptr 又存在 bptr,某些编译器会将其优化,合并为一个指针。

没有虚继承:

// 间接基类A
class A{
protected:
    int m_a;
};
// 直接基类B
class B: public A{
protected:
    int m_b;
};
// 直接基类C
class C: public A{
protected:
    int m_c;
};
// 派生类D
class D: public B, public C{
public:
    void seta(int a)
    {
        //m_a = a;     //命名冲突
        A::m_a = a;    //命名不再冲突
    }
    void setb(int b){
        m_b = b; //正确
    }
    void setc(int c){
        m_c = c; //正确
    } 
    void setd(int d){
        m_d = d; //正确
    } 
private:
    int m_d;
};
int main(){
    D d;
    return 0;
}

有虚继承:

// 间接基类A
class A{
protected:
    int m_a;
};
// 直接基类B
class B: virtual public A{
protected:
    int m_b;
};
// 直接基类C
class C: virtual public A{
protected:
    int m_c;
};
//派生类D
class D: public B, public C{
public:
    void seta(int a){
        m_a = a; //正确
    }
    void setb(int b){
        m_b = b; //正确
    }
    void setc(int c){
        m_c = c; //正确
    } 
    void setd(int d){
        m_d = d; //正确
    } 
private:
    int m_d;
};

17. 哪 些函数不能是虚函数?把你知道的都说一说

  1. 构造函数,构造函数初始化对象,派生类必须知道基类函数干了什么,才能进行构造;当有虚函数时,每一个类有一个虚表,每一个对象有一个虚表指针,虚表指针在构造函数中初始化。

  2. 内联函数,内联函数表示在编译阶段进行函数体的替换操作,而虚函数意味着在运行期间进行类型确定,所以内联函数不能是虚函数。

  3. 静态函数,静态函数不属于对象属于类,静态成员函数没有 this 指针,因此静态函数设置为虚函数没有任何意义。

  4. 友元函数,友元函数不属于类的成员函数,不能被继承。对于没有继承特性的函数没有虚函数的说法。

  5. 普通函数,普通函数不属于类的成员函数,不具有继承特性,因此普通函数没有虚函数。

  6. 模板函数,每个含有虚函数的类中都有一个虚函数表,该虚函数表存储着该类的所有的虚函数的地址。然而,当虚函数为模板函数时,由于编译阶段无法确定类的虚函数表的大小,因此编译器禁止这种用法。这是因为编译器在编译一个文件时并不知道其他文件对该类的虚函数的调用情况,所以无法确定模板虚函数的实例化个数。

18. 什 么是纯虚函数,与虚函数的区别

纯虚函数首先是虚函数,其次它没有函数体,取而代之的是用 “=0”。

既然是虚函数,它的函数指针会被存在虚函数表中,由于纯虚函数并没有具体的函数体,因此它在虚函数表中的值就为 0,而具有函数体的虚函数则是函数的具体地址。

一个类中如果有纯虚函数的话,称其为抽象类。抽象类不能用于实例化对象,否则会报错。抽象类一般用于定义一些公有的方法。子类继承抽象类也必须实现其中的纯虚函数才能实例化对象。

举个例子:

#include <iostream>
using namespace std;

class Base
{
public:
    virtual void fun1()
    {
        cout << "普通虚函数" << endl;
    }
    virtual void fun2() = 0;
    virtual ~Base() {}
};

class Son : public Base
{
public:
    virtual void fun2() 
    {
        cout << "子类实现的纯虚函数" << endl;
    }
};

int main()
{
    Base* b = new Son;
    b->fun1(); //普通虚函数
    b->fun2(); //子类实现的纯虚函数
    return 0;
}

虚函数和纯虚函数区别?

  • 虚函数是为了实现动态编联产生的,目的是通过基类类型的指针指向不同对象时,自动调用相应的、和基类同名的函数(使用同一种调用形式,既能调用派生类又能调用基类的同名函数)。虚函数需要在基类中加上 virtual 修饰符修饰,因为 virtual 会被隐式继承,所以子类中相同函数都是虚函数。当一个成员函数被声明为虚函数之后,其派生类中同名函数自动成为虚函数,在派生类中重新定义此函数时要求函数名、返回值类型、参数个数和类型全部与基类函数相同

  • 纯虚函数只是相当于一个接口名,但含有纯虚函数的类不能够实例化。

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

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

相关文章

VAuditDemo审计之二次注入漏洞

目录 VAuditDemo二次注入漏洞 搜索危险函数&#xff0c;用户可控点 regCheck.php messageSub.php message.php 漏洞调用链 漏洞错误利用过程 注册用户 xxxx, 发表payload留言 漏洞正确利用过程 注册用户 wwww\ 退出用户 wwww\\ 使用 wwww\ 登录 发表留言 替换dat…

《javaEE篇》--定时器

定时器概念 当我们不需要某个线程立刻执行&#xff0c;而是在指定时间点或指定时间段之后执行&#xff0c;假如我们要定期清理数据库里的一些信息时&#xff0c;如果每次都手动清理的话就太麻烦&#xff0c;所以就可以使用定时器。定时器就可以比作一个闹钟&#xff0c;可以让…

C++ 设计模式(6. 适配器模式)

适配器模式Adapter Pattern是一种结构型设计模式&#xff0c;它可以将一个类的接口转换成客户希望的另一个接口&#xff0c;主要目的是充当两个不同接口之间的桥梁&#xff0c;使得原本接口不兼容的类能够一起工作。基本结构 Target 是目标接口&#xff0c;Adaptee 是需要适配的…

微信小程序实例代码解读

以微信 小程序开发工具给的示例代码为例&#xff1a; 主页代码&#xff1a; index.wxml 这个文件是一个微信小程序页面的 WXML 结构,主要功能是展示一个快速开始教程的步骤和内容。 源代码&#xff1a; <!--index.wxml--> <view class"container">&l…

ZK-Rollups测评

1. 引言 Matter Labs团队和多个高校研究人员一起&#xff0c;发布2024年论文《Analyzing and Benchmarking ZK-Rollups》&#xff0c;开源代码见&#xff1a; https://github.com/StefanosChaliasos/zkrollup-benchmarking&#xff08;Python&#xff09; 其中&#xff1a; …

安装MySQL入门基础指令

一.安装MySQL(以5.7版本为例) 1.一路默认安装&#xff0c;截图供大家参考 修改自己window安装名字即可 2.配置环境变量 C:\Program Files\MySQL\MySQL Server 5.7\bin 写入系统环境变量即可在window窗口使用其服务了 3.登录MySQL服务 进入控制台输入命令 mysql -u root …

运维小技能:基于Windows系统和‌Linux系统,以tomcat为案例,讲解如何新增自启动服务。

文章目录 引言‌I Linux系统‌(以CentOS为例)基础知识:运行级别(run level)基于chkconfig 工具,设置服务启动类型。基于systemctl 新增系统服务II 基于Windows系统设置服务自启动的常规操作安装多个tomcat服务,并设置自启动。III 扩展制定定时任务优化停止Tomcat服务命令引…

ESP32Cam人工智能教学20

ESP32Cam人工智能教学20 ESP32Cam专用APP 这次我们专门为ESP32Cam量身定制一个手机APP。手机APP是客户端&#xff0c;利用Socket连接ESP32Cam&#xff0c;ESP32Cam成了服务器&#xff0c;实现Socket全双工的数据传输模式&#xff0c;还可以一边显示摄像头图像&#xff0c;一边…

【Canvas与诗词】北岛诗《献给遇罗克》节选(以太阳的名义...)

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>以太阳的名义</title><style type"text/css">…

基类没有虚析构,即使派生类使用智能指针也一定会内存泄漏

实验 定义一个基类和一个派生类 class Base { public:virtual ~Base() default; };class Derive :public Base { public:std::shared_ptr<int> sp{new int{0},[](int *p){delete p;std::cout << "删除器" << endl;},}; };main 函数执行如下代码…

作业08.21

服务器&#xff1a; #include <myhead.h>#define SER_PORT 6666 #define SER_IP "127.0.0.1"int find_client(int *client_arr, int len, int client) {for(int i0; i<len; i){if(client_arr[i] client){return i;}}return -1; }void remove_client(int *…

Mac 使用vscode 创建vue项目后修改文件提示:权限不足,以超级用户身份重试

项目场景&#xff1a; Mac 安装了全局 vue-cli 插件后&#xff0c;使用webpack 创建vue项目&#xff0c;打开项目&#xff0c;选择信任所有文件夹&#xff0c;然后正常编写代码&#xff0c;并对项目中的文件进行修改&#xff0c;点击保存的时候提示&#xff1a;保存“webpack.…

Vue3+Ts封装类似el-dialog的对话框组件

提供11个字段对dialog组件进行控制&#xff1a; modelValue: 对话框显示隐藏控制, width: 控制对话框的宽度, height&#xff1a;控制对话框的高度, top: 控制对话框个距离顶部的距离, title: 控制对话框的标题, appendToBody: 是否将对话框添加至body, closeOnClickModa…

GX Works2的使用方法

目录&#xff1a; 1、概述 2、硬件连接 3、录入与修改程序 1&#xff09;进入编辑按F2或点击“写入模式”图标 2&#xff09;修改部分元件 3&#xff09;注释 4&#xff09;改变显示触点数 4、软仿真与在线仿真 1&#xff09;软仿真 2&#xff09;在线仿真 5、P…

Linux源码阅读笔记-USB设备驱动架构

总线速度及主机控制器 USB系统架构 USB系统主机端提供为4个引脚的A型接口&#xff0c;USB外围设备通过4个引脚的B型接口和主机端连接。那4个引脚&#xff08;一条电压线VBUS、一条地线GND、一条正方向传输数据的D和一条反方向传输数据的D-线。&#xff09;USB主机和USB设备收发…

2024年翻译神器:探索四款好用的翻译工具!

因为有了一些翻译工具的存在&#xff0c;语言障碍已经渐渐不成问题。接下来就为大家推荐几款好用的翻译工具&#xff01; 福昕在线翻译 链接&#xff1a; https://fanyi.pdf365.cn/ 福昕在线翻译以其简洁的界面和强大的翻译能力&#xff0c;成为用户跨越语言障碍的首选。它…

独立站PrestaShop安装

独立站PrestaShop安装 独立站PrestaShop安装系统需求下载PrestaShop浏览器下载命令行下载 解压PrestaShop创建数据库移动PrestaShop源码到web目录composer安装依赖包nginx配置访问域名进入安装页面选择语言许可协议系统兼容性店铺信息Content of your store系统配置数据库店铺安…

金矢之lian,非你莫蜀:金矢留学携手16所英国大学共襄成都盛会

碧海蓝天的东海岸&#xff0c;盛夏的热烈未尽&#xff0c;草书云山如锦绣的天府之国&#xff0c;初秋的凉意渐起。近一年的忙碌与等待之后&#xff0c;2024年英国秋季入学申请已近尾声&#xff0c;如愿以偿拿到了录取的同学们&#xff0c;欢欣鼓舞的进入申请签证甚至预定行程机…

nginx实例

nginx的由来 Nginx是由1994年毕业于俄罗斯国立莫斯科鲍曼科技大学的同学为俄罗斯rambler.ru公司开发的&#xff0c;开发工作最早从2002年开始&#xff0c;第一次公开发布时间是2004年10月4日&#xff0c;版本号是0.1.0。2019年3月11日F5 与 NGINX达成协议,F5 将收购 NGINX 的所…