C++面试基础系列-abstract

2024-08-22 09:36

本文主要是介绍C++面试基础系列-abstract,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

系列文章目录


文章目录

  • 系列文章目录
  • C++面试基础系列-abstract
    • Overview
    • 1.abstract关键点
    • 2.C++ 抽象类和纯虚函数的例子
    • 3.abstract重点
    • 关于作者


C++面试基础系列-abstract

Overview

在C++中,abstract这个概念主要与抽象类(Abstract Class)相关。抽象类是一种不能被实例化的类,它通常包含至少一个纯虚函数(Pure Virtual Function)。抽象类用于定义接口或行为规范,可以被其他类继承并实现具体的功能。

1.abstract关键点

以下是一些关于C++中抽象类的关键点:

  • 纯虚函数:
    • 纯虚函数是在基类中声明但没有实现的虚函数,其声明方式是在函数声明的末尾加上= 0。
    • 例如:virtual void doSomething() = 0;
  • 抽象类的定义:
    • 包含至少一个纯虚函数的类就是抽象类。
    • 抽象类不能被直接实例化,但可以被用作其他类的基类。
  • 继承抽象类:
    • 派生类必须实现基类中的所有纯虚函数,否则派生类也会是抽象类。
  • 接口定义:
    • 抽象类通常用于定义接口,让不同的派生类实现相同的接口。
  • 多态性:
    • 抽象类支持多态性,可以通过基类指针或引用调用派生类重写的虚函数。
      示例:
// 抽象类声明
class Shape {
public:virtual void draw() const = 0;  // 纯虚函数virtual ~Shape() {}  // 虚析构函数,确保派生类析构正确性
};// 派生类实现抽象类
class Circle : public Shape {
public:void draw() const override {// 绘制圆形的代码}
};// 使用抽象类
Shape* shape = new Circle();
shape->draw();
delete shape;
  • 抽象类的作用:
    • 强制实现接口:确保所有派生类都实现了抽象类中定义的纯虚函数。
    • 代码复用:基类可以提供一些通用的实现,派生类可以重写或继承这些实现。
  • 设计原则:
    • 遵循里氏替换原则(Liskov Substitution Principle),确保派生类可以替换其基类。
  • 注意事项:
    • 抽象类通常包含虚析构函数,以确保派生类的析构函数被正确调用。
  • C++11及以后版本:
    • C++11引入了final关键字,可以修饰类或成员函数,表示它们不能被进一步继承或重写。

抽象类是C++面向对象编程中的一个重要概念,它有助于实现代码的模块化和可扩展性。通过使用抽象类,开发者可以定义清晰的接口,并在不同的派生类中实现这些接口的具体行为。

2.C++ 抽象类和纯虚函数的例子

  • 在这个例子中,Shape 是一个抽象类,它定义了一个纯虚函数 getArea。
    • Circle 和 Rectangle 是 Shape 的派生类,它们分别实现了 getArea 函数。
    • 由于 Shape 是抽象类,我们不能直接创建它的实例,但可以创建 Circle 和 Rectangle 的实例。
#include <iostream>// 抽象基类
class Shape {
public:// 纯虚函数,用于计算面积virtual double getArea() const = 0;// 虚析构函数virtual ~Shape() {}
};// 派生类 Circle
class Circle : public Shape {
public:// 构造函数Circle(double radius) : radius(radius) {}// 实现基类的纯虚函数double getArea() const override {return 3.14159 * radius * radius;}private:double radius;
};// 派生类 Rectangle
class Rectangle : public Shape {
public:// 构造函数Rectangle(double width, double height) : width(width), height(height) {}// 实现基类的纯虚函数double getArea() const override {return width * height;}private:double width, height;
};int main() {// 由于 Shape 是抽象类,不能直接实例化// Shape shape; // 错误Circle circle(5.0);Rectangle rectangle(4.0, 6.0);std::cout << "Circle area: " << circle.getArea() << std::endl;std::cout << "Rectangle area: " << rectangle.getArea() << std::endl;return 0;
}

3.abstract重点

  • 纯虚函数使一个类变成抽象类
  • 抽象类类型的指针和引用
  • 如果我们不在派生类中覆盖纯虚函数,那么派生类也会变成抽象类
  • 抽象类可以有构造函数
  • 构造函数不能是虚函数,而析构函数可以是虚析构函数
// 抽象类
class Base  {
public:Base(){ cout << "Constructor: Base" << endl; }virtual ~Base(){ cout << "Destructor : Base" << endl; }virtual void func() = 0;
};class Derived: public Base {
public:Derived(){ cout << "Constructor: Derived" << endl; }~Derived(){ cout << "Destructor : Derived" << endl;}void func(){cout << "In Derived.func()." << endl;}
};

当基类指针指向派生类对象并删除对象时,我们可能希望调用适当的析构函数。
如果析构函数不是虚拟的,则只能调用基类析构函数。


关于作者

  • 本文作者:WeSiGJ
  • 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
  • GitHub:https://github.com/wesigj/CPLUSCPLUSBOYS
  • CSDN:https://blog.csdn.net/wesigj
  • 微博:
  • 微信公众号:WeSiGJ——喜欢就关注一下吧

请添加图片描述

这篇关于C++面试基础系列-abstract的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1095901

相关文章

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

数据库面试必备之MySQL中的乐观锁与悲观锁

《数据库面试必备之MySQL中的乐观锁与悲观锁》:本文主要介绍数据库面试必备之MySQL中乐观锁与悲观锁的相关资料,乐观锁适用于读多写少的场景,通过版本号检查避免冲突,而悲观锁适用于写多读少且对数... 目录一、引言二、乐观锁(一)原理(二)应用场景(三)示例代码三、悲观锁(一)原理(二)应用场景(三)示例

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve

mysql的基础语句和外键查询及其语句详解(推荐)

《mysql的基础语句和外键查询及其语句详解(推荐)》:本文主要介绍mysql的基础语句和外键查询及其语句详解(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋... 目录一、mysql 基础语句1. 数据库操作 创建数据库2. 表操作 创建表3. CRUD 操作二、外键

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元