首页 > 编程语言 >C++ Practical-1 day6

C++ Practical-1 day6

时间:2024-09-25 09:21:42浏览次数:3  
标签:函数 day6 基类 C++ Practical Shape 纯虚 派生类 抽象类

系列文章目录

点击直达——文章总目录


文章目录


C++ Practical-1 day6

Overview

  • C++不练习coding,就相当于空中楼阁,基础不扎实
  • 光吃不干,等于没吃

1.abstract_class 抽象类

在C++中,抽象类是一种不能被实例化的类,它通常作为基类使用,用于定义一个接口或规范,确保派生类遵循某些方法。抽象类通过包含至少一个纯虚函数(pure virtual function)来实现。

1.1.抽象类的特点

  1. 纯虚函数:抽象类至少包含一个纯虚函数。纯虚函数没有实现,使用= 0声明。

  2. 不能被实例化:由于抽象类不提供完整的实现,因此不能创建其实例。

  3. 派生类必须覆盖所有纯虚函数:派生类必须覆盖基类中的所有纯虚函数,除非派生类也是抽象类。

  4. 虚析构函数:通常在抽象类中定义虚析构函数,以确保删除派生类对象时正确调用派生类的析构函数。

1.2.示例:抽象类

#include <iostream>
#include <memory>

// 抽象类
class Shape {
public:
    // 纯虚函数
    virtual void draw() const = 0;

    // 虚析构函数
    virtual ~Shape() {}
};

// 派生类
class Circle : public Shape {
public:
    void draw() const override {
        std::cout << "Drawing a circle." << std::endl;
    }
};

// 另一个派生类
class Rectangle : public Shape {
public:
    void draw() const override {
        std::cout << "Drawing a rectangle." << std::endl;
    }
};

int main() {
    // 使用基类指针指向派生类对象
    std::unique_ptr<Shape> shape1(new Circle());
    std::unique_ptr<Shape> shape2(new Rectangle());

    shape1->draw(); // 调用Circle的draw函数
    shape2->draw(); // 调用Rectangle的draw函数

    return 0;
}

在这个例子中,Shape是一个抽象类,它包含一个纯虚函数drawCircleRectangle是派生自Shape的类,它们都覆盖了draw函数。在main函数中,我们使用Shape指针来指向CircleRectangle对象,并调用它们的draw函数。

1.3.注意事项

  1. 接口定义:抽象类通常用于定义接口,它规定了派生类必须实现的函数。

  2. 多态:抽象类通常与多态一起使用,允许通过基类指针或引用来调用派生类中覆盖的虚函数。

  3. 抽象类和虚函数:抽象类可以包含多个纯虚函数和普通虚函数。普通虚函数提供了默认实现,而纯虚函数没有。

  4. 抽象类和继承:派生类可以从多个抽象类继承,也可以是另一个抽象类的抽象类。

  5. 抽象类的实现:虽然抽象类不能被实例化,但它们可以包含成员函数的实现,这些实现可以被派生类继承。

  6. 工厂模式:抽象类经常与工厂模式结合使用,用于创建一系列相关对象。

抽象类是C++中实现面向对象设计原则的重要工具,它有助于定义清晰的接口和促进代码的模块化。

2.virtual_function 虚函数

在C++中,虚函数用于实现多态性,允许通过基类指针或引用调用派生类中覆盖的函数。以下是一个使用虚函数的编程实例:

2.1.示例:动物叫声的多态性

#include <iostream>

// 基类
class Animal {
public:
    virtual void speak() const {
        std::cout << "The animal makes a sound." << std::endl;
    }

    virtual ~Animal() {} // 虚析构函数
};

// 派生类:狗
class Dog : public Animal {
public:
    void speak() const override {
        std::cout << "The dog barks." << std::endl;
    }
};

// 派生类:猫
class Cat : public Animal {
public:
    void speak() const override {
        std::cout << "The cat meows." << std::endl;
    }
};

int main() {
    Animal* myAnimal = nullptr;

    Dog myDog;
    myAnimal = &myDog;
    myAnimal->speak(); // 输出: The dog barks.

    Cat myCat;
    myAnimal = &myCat;
    myAnimal->speak(); // 输出: The cat meows.

    return 0;
}

在这个例子中,Animal是一个基类,它有一个虚函数speakDogCat是派生自Animal的类,它们都覆盖了speak函数。在main函数中,我们使用Animal指针myAnimal来指向DogCat对象,并调用它们的speak函数。

2.2.示例:计算图形的面积

#include <iostream>

// 基类:形状
class Shape {
public:
    virtual double area() const = 0; // 纯虚函数
    virtual ~Shape() {} // 虚析构函数
};

// 派生类:圆形
class Circle : public Shape {
private:
    double radius;
public:
    Circle(double r) : radius(r) {}

    double area() const override {
        return 3.14159 * radius * radius;
    }
};

// 派生类:矩形
class Rectangle : public Shape {
private:
    double width, height;
public:
    Rectangle(double w, double h) : width(w), height(h) {}

    double area() const override {
        return width * height;
    }
};

int main() {
    const double pi = 3.14159;
    Shape* shape;

    Circle circle(5); // 半径为5的圆
    shape = &circle;
    std::cout << "Circle area: " << shape->area() << std::endl; // 输出圆形的面积

    Rectangle rectangle(4, 6); // 宽4高6的矩形
    shape = &rectangle;
    std::cout << "Rectangle area: " << shape->area() << std::endl; // 输出矩形的面积

    return 0;
}

在这个例子中,Shape是一个抽象基类,它有一个纯虚函数areaCircleRectangle是派生自Shape的类,它们都覆盖了area函数。在main函数中,我们使用Shape指针shape来指向CircleRectangle对象,并调用它们的area函数。

2.3.注意事项

  1. 多态性:虚函数允许多态性,使得可以通过基类指针或引用来调用派生类中覆盖的函数。

  2. 抽象基类:包含纯虚函数的类是抽象基类,不能被实例化。

  3. 派生类覆盖虚函数:派生类可以使用override关键字来覆盖基类的虚函数。

  4. 虚析构函数:在基类中声明虚析构函数,以确保删除派生类对象时正确调用派生类的析构函数。

  5. 动态类型识别:可以使用dynamic_cast在运行时安全地将基类指针或引用转换为派生类指针或引用。

虚函数是C++中实现多态性的关键,使得代码更加灵活和可扩展。


关于作者

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

相关文章

  • 自梳理C++八股
    1.左右值引用的理解回答:“左右值引用是C++11引入的一项重要特性,用于优化资源管理和提升性能。具体来说:左值引用(LvalueReference):左值引用可以类比为对象的别名,它允许多个引用共享一个实体对象,常用于函数参数传递以避免对象拷贝。左值引用只能绑定到一个命名的持久对象,适合用......
  • 【C++】STL详解之string类
    本次内容大纲:什么是STLSTL(standardtemplatelibaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。STL的版本原始版本AlexanderStepanov、MengLee在惠普实验室完成的原始版本,本着开源精神,他们声明允许任......
  • C++ IO 类
    IO库:istream(输入流)类型,提供输入操作。ostream(输出流)类型,提供输出操作。cin,一个istream对象,从标准输入读取数据。cout,一个ostream对象,向标准输出写入数据。cerr,一个ostream对象,通常用于输出程序错误消息,写入到标准错误。>>运算符,用来从一个istream对象读取输入数据。<......
  • C++语言的词汇
    关键字关键字:也称保留字,它是由C++语言本身预先定义好的一类单词基本数据类型和布尔类型int、float、double、char、bool:用于声明整型、浮点型、字符型和布尔型变量。true、false:布尔类型的两个字面量值。复杂数据类型与类class:用于声明类,是C++面向对象编程的基础。str......
  • 【C++基础知识——迭代器 引入】
    问题引入#include<iostream>#include<map>#include<string>intmain(){//定义一个std::map容器std::map<std::string,int>ageMap;ageMap["Alice"]=30;ageMap["Bob"]=25;ageMap["Charlie&q......
  • java_day6_this关键字、构造方法、static关键字、工具类、文档注释
    一、this关键字this代表的是调用该方法的当前对象【谁调用了该方法,this就代表那个对象】this:代表的是调用当前方法的对象this可以使用对象中的成员变量,成员方法,构造方法变量查找规则:就近原则先在方法中查找变量,若找到就使用若方法中没有该变量,去成......
  • C++基础
    1.第一个C++程序#include<iostream>//固定格式usingnamespacestd;intmain(){inta=10//定义变量;cout<<a<<endl;//打印变量system("pause");return0;}2.常量与变量的类型只要变量前加const与#define(宏常量)3.关键字3......
  • C++中的类型推断机制
    1.decltype的作用decltype是C++11引入的一个关键字,用来推断表达式的类型。它返回的是表达式的精确类型,包括引用和const限定符等。例子:intx=5;decltype(x)y=x;//y的类型是int在这个例子中,decltype(x)返回int,因为x是一个int类型的变量,所以y的类型也被推......
  • 【C++】类和对象——下
    一.类和对象(下)1.再探构造函数•之前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅式,就是初始化列表,初始化列表的使⽤⽅式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成员列表,每个"成员变量"后⾯跟⼀个放在括号......
  • 《 C++ 修炼全景指南:十二 》用红黑树加速你的代码!C++ Set 和 Map 容器从入门到精通
    摘要本文详细介绍了基于红黑树实现的Set和Map容器,包括其底层设计原理、插入和删除操作的实现细节、性能分析与优化策略,以及实际应用场景和未来发展方向。通过采用红黑树的数据结构,Set和Map容器能够高效地处理有序数据,保持O(logn)的时间复杂度,适用于各种数据存储......