首页 > 编程语言 >C++ 抽象类与纯虚函数详解:理论与实战

C++ 抽象类与纯虚函数详解:理论与实战

时间:2024-06-09 11:32:43浏览次数:30  
标签:函数 派生类 C++ Shape 纯虚 基类 抽象类

抽象基类为什么不能创建对象?

抽象类是一种特殊的类,它被设计用来作为其他类的基类,不能实例化为对象。以下是关于抽象类和纯虚函数的详细解释:

1. 抽象类的定义:
  • 抽象类:带有纯虚函数的类称为抽象类。抽象类不能实例化对象,只能作为基类被继承。
  • 纯虚函数:一种没有实现的虚函数,其定义格式为:
    virtual <返回类型> <函数名>(<参数列表>) = 0;
    
2. 抽象类的作用:

抽象类的主要作用是定义一个接口,为派生类提供公共的根,使派生类实现这些接口。

3. 使用抽象类时的注意事项:
  • 抽象类只能用作基类,不能创建抽象类的对象。
  • 派生类如果没有实现基类的纯虚函数,该派生类仍然是一个抽象类。
  • 派生类实现了基类的所有纯虚函数后,才变成具体类,能够实例化对象。
4. 纯虚函数的引入原因:
  • 多态:为了实现多态特性,需要在基类中定义虚函数。
  • 合理性:基类自身生成对象在很多情况下是不合适的。例如,Animal 类可以派生出 Tiger 和 Peacock 等子类,但 Animal 本身不应生成对象。
示例代码:
#include <iostream>
using namespace std;

// 基类:Shape
class Shape {
public:
    // 纯虚函数,要求派生类一定要实现
    virtual void draw() const = 0;
    virtual double area() const = 0;
    // 虚析构函数确保派生类对象被正确销毁
    virtual ~Shape() {}
};

// 派生类:Circle
class Circle : public Shape {
public:
    Circle(double r) : radius(r) {}
    void draw() const override {
        cout << "Drawing a Circle." << endl;
    }
    double area() const override {
        return 3.14159 * radius * radius;
    }
private:
    double radius;
};

// 派生类:Rectangle
class Rectangle : public Shape {
public:
    Rectangle(double w, double h) : width(w), height(h) {}
    void draw() const override {
        cout << "Drawing a Rectangle." << endl;
    }
    double area() const override {
        return width * height;
    }
private:
    double width, height;
};

int main() {
    // 抽象类不能实例化对象
    // Shape shape; // 错误,Shape 是抽象类

    // 使用抽象类指针或引用指向具体类对象
    Shape* shapes[2];
    shapes[0] = new Circle(5);
    shapes[1] = new Rectangle(4, 6);

    for (int i = 0; i < 2; ++i) {
        shapes[i]->draw();
        cout << "Area: " << shapes[i]->area() << endl;
    }

    // 释放内存
    for (int i = 0; i < 2; ++i) {
        delete shapes[i];
    }

    return 0;
}
代码解析:
  • 纯虚函数
    • 在 Shape 基类中定义了两个纯虚函数 draw() 和 area(),表示 Shape 是一个抽象类。
  • 派生类的实现
    • Circle 和 Rectangle 类都是从 Shape 类派生出来的,并实现了纯虚函数 draw() 和 area()
  • 多态性
    • 在 main 函数中,使用 Shape 类指针数组来存储不同的 Shape 对象,体现了多态性。
    • 调用 draw() 和 area() 方法时,实际调用的时派生类实现的函数,演示了运行时的多态性。

通过这些内容和示例代码,我们展示了抽象类和纯虚函数的概念和应用,帮助你更好地理解为什么抽象类不能实例化,以及如何运用它们来实现多态性的设计模式

标签:函数,派生类,C++,Shape,纯虚,基类,抽象类
From: https://blog.csdn.net/m0_72877724/article/details/139549031

相关文章

  • 深入解析C++中自动生成默认构造函数的五种情况
    自动生成默认构造函数的情况以及相关解释在C++中,当一个类没有任何用户定义的构造函数时,编译器会自动为这个类生成一个默认构造函数。以下是具体情况的解释以及示例:1.带有默认构造函数的类成员对象如果一个类没有任何构造函数,但它含有一个成员对象,而该成员对象有默认构造......
  • 为什么C++友元函数必须在类内部声明?解析与案例
    友元函数是C++中独特的编程结构,允许一个非成员函数或者其他类访问另一个类的私有和保护数据成员。友元在很多情况下是非常有用的,比如操作符重载、类间紧密合作等。为什么需要在类内部声明友元函数?访问权限:友元函数需要访问类的私有和保护数据成员。为此,必须在类内部声明,以便......
  • 栈经典题目(C++)
    文章目录前言一、删除字符串中的所有相邻重复项1.题目解析2.算法原理3.代码编写二、基本计算器II1.题目解析2.算法原理3.代码编写三、字符串解码1.题目解析2.算法原理3.代码编写四、验证栈序列1.题目解析2.算法原理3.代码编写总结前言一、删除字符串中的所有......
  • 【四种语言一网打尽(C\C++\Python\Golang)】L1-005 考试座位号
    L1-005考试座位号每个PAT考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座。但有些考生迟到了,试机已经结束,他们只能拿着......
  • C++ 对拍
    准备timeb毫秒级随机数文件这里以P1001A+BProblem为例。std.cpp-std.exe(std.lnk)#include<bits/stdc++.h>usingnamespacestd;signedmain(){intx,y;cin>>x>>y;cout<<x+y<<endl;return0;}force.cpp-force.exe#......
  • vscode编译c/c++找不到jni.h文件
    解决办法:一、下载JDK访问Oracle官网的Java下载页面:JavaDownloads|Oracle选择适合您操作系统的JDK版本:对于Windows,选择“Windowsx64”或“Windowsx86”(取决于您的系统是64位还是32位)。对于Linux,选择适合您Linux发行版的压缩包。对于Mac,选择“.dmg”或“.pkg”安装......
  • 【C++/STL】list(常见接口、模拟实现、反向迭代器)
     ......
  • C++ OpenCV 图像分类魔法:探索神奇的模型与代码
    ⭐️我叫忆_恒心,一名喜欢书写博客的研究生......
  • C++20协程接口说明
    等待体的接口说明: boolawait_ready()表达了等待体对象是否准备就绪,返回false表示没有准备好,返回true表示准备好了,这个返回值决定了等待体的执行流程。 boolawait_suspend(Coro::coroutine_handle<Task::promise_type>)当await_ready返回fasle时,进入此函数执行,如果await_r......
  • 柔性数组+总结C/C++中程序内存区域划分
    柔性数组一.柔性数组1.柔性数组的定义2.柔性数组的特点3.柔性数组的使用4.柔性数组的优势二.总结C/C++中程序内存区域划分前言:也许你从来没有听说过柔性数组这个概念,但是它确实是存在的。一.柔性数组1.柔性数组的定义C99中,结构体中的最后一个元素允许是未知大小的......