首页 > 编程语言 >C++纯虚函数的理解,纯虚函数和派生类的关系。

C++纯虚函数的理解,纯虚函数和派生类的关系。

时间:2024-07-01 17:29:55浏览次数:23  
标签:函数 实现 void C++ 纯虚 派生类 public

在 C++ 中,纯虚函数(pure virtual function)是一种特殊的虚函数,它在基类中没有实现,只定义了一个接口,要求派生类必须提供具体实现。纯虚函数的定义方式在接口设计和多态性中非常有用。

纯虚函数的定义和语法

在 C++ 中,纯虚函数的定义使用以下语法:

class Base {
public:
    virtual void pureVirtualFunction() = 0;  // 纯虚函数
};
  • 这里 = 0 表示这是一个纯虚函数,它没有在 Base 类中实现。
  • 任何派生类都必须实现 pureVirtualFunction,否则该派生类也会变成抽象类,不能被实例化。

抽象类

包含至少一个纯虚函数的类称为抽象类(abstract class)。抽象类不能直接创建对象(实例化)。它主要用于作为接口类或基类,要求派生类实现特定的行为。

例如:

class Shape {
public:
    virtual void draw() = 0;  // 纯虚函数
    virtual double area() = 0;  // 纯虚函数
};

class Circle : public Shape {
public:
    void draw() override {
        // Circle 的具体绘制实现
    }

    double area() override {
        // 计算并返回 Circle 的面积
    }
};

class Rectangle : public Shape {
public:
    void draw() override {
        // Rectangle 的具体绘制实现
    }

    double area() override {
        // 计算并返回 Rectangle 的面积
    }
};

在上面的例子中,Shape 是一个抽象类,定义了纯虚函数 drawarea。任何继承自 Shape 的类(例如 CircleRectangle)都必须实现这些函数。

纯虚函数的要求和特性

示例代码

下面是一个实际使用纯虚函数的示例:

  1. 纯虚函数不能在基类中实现: 纯虚函数在基类中没有实现,只有声明。这意味着它仅仅定义了一个接口或合同,具体实现由派生类提供。

  2. 派生类必须实现纯虚函数: 任何继承包含纯虚函数的类的非抽象派生类,必须实现这些纯虚函数,否则该派生类也会成为抽象类。

  3. 抽象类不能实例化: 包含纯虚函数的类不能直接创建对象(实例化)。它们通常用于定义接口和通用行为,强制派生类提供具体实现。

  4. 可以在派生类中覆盖实现: 派生类可以提供自己对纯虚函数的实现,这也是多态性的基础。例如,上面的 CircleRectangle 都实现了 Shape 的纯虚函数。

  5. 可以有实现的纯虚函数: 虽然纯虚函数本身在基类中没有实现,但在一些特殊情况下,可以为纯虚函数提供一个默认的实现,只是这种实现不会改变它作为纯虚函数的性质。例如:

    class Base {
    public:
        virtual void pureVirtualFunction() = 0;  // 纯虚函数
    };
    
    void Base::pureVirtualFunction() {
        // 纯虚函数的默认实现
    }
    

  6. 这种情况下,派生类仍然需要实现 pureVirtualFunction,否则它们将无法实例化。

  7. 使用纯虚函数的场景

  8. 定义接口: 纯虚函数常用于定义接口类,指定某些操作的合同,而不提供具体实现。例如,定义一个通信接口,要求所有的通信协议实现类都必须实现发送和接收方法。

  9. 强制派生类实现某些功能: 通过将函数声明为纯虚,基类可以强制派生类提供这些函数的具体实现,从而确保派生类具有一致的行为。

  10. 支持多态: 使用纯虚函数可以在运行时通过基类指针或引用调用派生类的实现,实现多态行为。

    #include <iostream>
    
    class Animal {
    public:
        virtual void speak() = 0;  // 纯虚函数
    };
    
    class Dog : public Animal {
    public:
        void speak() override {
            std::cout << "Woof!" << std::endl;
        }
    };
    
    class Cat : public Animal {
    public:
        void speak() override {
            std::cout << "Meow!" << std::endl;
        }
    };
    
    int main() {
        Animal* dog = new Dog();
        Animal* cat = new Cat();
    
        dog->speak();  // 输出: Woof!
        cat->speak();  // 输出: Meow!
    
        delete dog;
        delete cat;
    
        return 0;
    }
    

    在这个例子中,Animal 类定义了一个纯虚函数 speakDogCat 类必须实现 speak 函数。在 main 函数中,通过基类指针调用派生类的 speak 实现,实现了多态行为。

标签:函数,实现,void,C++,纯虚,派生类,public
From: https://blog.csdn.net/qq_44905692/article/details/140105618

相关文章

  • 【算法炼金术】让数字起舞:两数相加的C++艺术
    【算法炼金术】让数字起舞:两数相加的C++艺术一、引言:编织数字的魔法二、技术概述:数字的交响乐章技术定义核心特性代码示例:原味经典三、技术细节:数字的幕后故事原理解析难点剖析四、实战应用:数字的舞台秀应用场景问题与解决方案问题:大数相加易溢出五、优化与改进:数字......
  • 【算法】搜索插入位置:C++ 实现与深入理解
    【算法】搜索插入位置:C++实现与深入理解一、引言:C++算法的精髓与探索之旅二、技术概述:有序数组的探索定义与技术介绍核心特性和优势代码示例三、技术细节:二分查找的奥秘原理解析难点分析四、实战应用:排序数组的高效操作应用场景问题与解决方案五、优化与改进潜在问题......
  • c++ final 关键字
    在C++中,final是一个关键字,它主要用于两个上下文:类继承的终结:当你在类定义后使用final关键字时,这意味着该类不能被其他类继承。这是C++11引入的特性。classMyClassfinal{//...};//下面的代码会导致编译错误,因为MyClass是final的classDerivedClass:pub......
  • 使用不同函数打印torch.nn模型——print(model),named_children(),named_modules():
    创建模型创建一个具有三级嵌套的模型,结构如图:importtorchimporttorch.nnasnn#定义子子模块classSubSubModule(nn.Module):def__init__(self):super(SubSubModule,self).__init__()self.conv=nn.Conv2d(3,3,kernel_size=3,padding=1)......
  • c++使用matplotlibcpp,subplot() 报错问题-ubuntu22.04
    使用matplotlibcpp.h在C++代码中绘制图形plt::subplot();程序抛出运行时错误,terminatecalledafterthrowinganinstanceof'std::runtime_error'what():Calltosubplot()failed.解决方法:在matplotlibcpp.h文件中把PyTuple_SetItem(args,0,PyFloat_FromDouble(......
  • 内存管理-9-内存常用函数和宏
    基于msm-5.41.页与页帧号转换//include/asm-generic/memory_model.h#definepfn_to_page(pfn)(vmemmap+(pfn))#definepage_to_pfn(page)(unsignedlong)((page)-vmemmap)注:使能了CONFIG_SPARSEMEM_VMEMMAP才使用的是这一组宏。vmemmap是一个structpage*类......
  • C++知识点总结全系列 (05):IO 类的详细总结和分析
    1、基类istream和ostream(1)istreamA.What输入流的抽象类,是所有输入流类的基类B.Why(输入流的作用)用于从数据源(如文件、标准输入设备等)读取数据(2)ostreamA.What输出流的抽象类,是所有输出流类的基类B.Why(输出流的作用)输出流用于将数据写入到目标位置,例如......
  • C++ //练习 14.17 你在7.5.1节的练习7.40(第261页)中曾经选择并编写了一个类,你认为它应
    C++Primer(第5版)练习14.17练习14.17你在7.5.1节的练习7.40(第261页)中曾经选择并编写了一个类,你认为它应该含有相等运算符吗?如果是,请实现它;如果不是,解释原因。环境:LinuxUbuntu(云服务器)工具:vim 代码块classDate{ public: Date(); Date(size_ty,size_tm,siz......
  • 嵌入式Linux系统编程 — 5.5 sleep、usleep和nanosleep系统休眠函数
    目录1为什么需要休眠2 sleep、usleep和nanosleep函数2.1sleep函数2.2 usleep函数2.3 nanosleep函数3示例程序1为什么需要休眠有时需要将进程暂停或休眠一段时间,进入休眠状态之后,程序将暂停运行,直到休眠结束。以下是一些常见的休眠场景和作用:避免过载:在高......
  • 【FreeRTOS】两个Delay函数
    目录0前言1Delay函数1.1两个Delay函数1.2总结2程序2.1函数修改2.2总结0前言在我们实际开发过程中,一般都用事件开发不要使用死循环1Delay函数1.1两个Delay函数FreeRTOS中有两个Delay函数:vTaskDelay:至少等待指定个数的TickInterrupt才能变为就绪......