当前位置: 首页 > news >正文

c++指南 继承和多态

继承和多态

继承的概念

继承是面向对象编程的一个重要特性,它允许新创建的类(称为子类或派生类)继承现有类(称为基类或父类)的属性和方法。

基类与子类

基类:提供了可以被继承的属性和方法。
子类:继承了基类的属性和方法,并且可以添加新的属性和方法或重写继承的方法。

继承的类型

公有继承(public):子类继承基类的公有成员和保护成员,并且它们在子类中也是公有或保护的。
私有继承(private):子类继承基类的公有和保护成员,但它们在子类中变为私有的。
保护继承(protected):子类继承基类的公有和保护成员,但它们在子类中变为保护的。

多态性

多态性是对象可以有多种形式的能力。在C++中,多态性主要通过虚函数实现。

虚函数

虚函数是基类中的函数,允许在派生类中被重写(Override)。使用 virtual 关键字声明。

class Base {
public:virtual void show() { std::cout << "Base show" << std::endl; }
};class Derived : public Base {
public:void show() override { std::cout << "Derived show" << std::endl; }
};

抽象类

抽象类是不能被实例化的类,它至少包含一个纯虚函数。使用 = 0 来定义纯虚函数。

class AbstractBase {
public:virtual void pureVirtualFunc() = 0; // 纯虚函数
};class ConcreteClass : public AbstractBase {
public:void pureVirtualFunc() override {// 实现抽象类中的纯虚函数}
};

多态的实现

使用基类指针或引用指向派生类对象,可以实现动态多态性。

Base* basePtr = new Derived();
basePtr->show(); // 输出 "Derived show",展示了多态性
delete basePtr;

虚析构函数

在C++中,如果一个类是多态基类(即有一个或多个虚函数),则其析构函数应当被声明为虚函数。这是因为当通过基类指针删除派生类对象时,需要确保正确地调用派生类的析构函数,然后才是基类的析构函数。

class Base {
public:virtual ~Base() {std::cout << "Base destructor" << std::endl;}
};class Derived : public Base {
public:~Derived() {std::cout << "Derived destructor" << std::endl;}
};int main() {Base* basePtr = new Derived();delete basePtr; // 正确地调用Derived和Base的析构函数return 0;
}
输出为
Derived destructor
Base destructor

运算符重载与多态

运算符重载允许你定义类的运算符如何工作。当运算符被重载为成员函数时,它可以是虚函数,从而支持多态性。

例子

  1. 使用虚函数重载 == 运算符
class Base {
public:virtual bool operator==(const Base& other) const {// 默认实现,可能需要根据实际需求重写return this == &other;}
};class Derived : public Base {int value;
public:Derived(int v) : value(v) {}bool operator==(const Base& other) const override {// 重写 == 运算符以比较 Derived 对象const Derived* otherDerived = dynamic_cast<const Derived*>(&other);if (otherDerived) {return value == otherDerived->value;}return false;}
};
  1. 重载输出流运算符 <<
class Person {std::string name;
public:Person(const std::string& n) : name(n) {}friend std::ostream& operator<<(std::ostream& os, const Person& p) {os << "Person: " << p.name;return os;}
};class Employee : public Person {int id;
public:Employee(const std::string& n, int i) : Person(n), id(i) {}friend std::ostream& operator<<(std::ostream& os, const Employee& e) {os << static_cast<const Person&>(e); // 调用基类的输出os << ", ID: " << e.id;return os;}
};

在这个例子中,Employee 类重载了 << 运算符,输出 Employee 对象时,首先调用了基类 Person 的 << 运算符,然后添加了 Employee 特有的信息。

  1. 重载赋值运算符 =
class Data {int* array;size_t size;
public:Data(size_t s) : size(s), array(new int[s]) {}Data(const Data& other) : size(other.size), array(new int[other.size]) {std::copy(other.array, other.array + size, array);}Data& operator=(const Data& other) {if (this != &other) {delete[] array;size = other.size;array = new int[size];std::copy(other.array, other.array + size, array);}return *this;}~Data() {delete[] array;}
};

在这个例子中,赋值运算符 = 被重载以确保深拷贝数组,并且正确地处理自赋值的情况。


http://www.mrgr.cn/news/3414.html

相关文章:

  • HTTP/1.1
  • 好用的呼叫系统:天润融通,打造高效通信新体验
  • Hooks 「 useImperativeHandle 」子组件向父组件暴露方法
  • 驾驭时间之舟:SQL中时序数据处理的深度探索
  • Chainlit接入FastGpt接口快速实现自定义用户聊天界面
  • 探索CSS的未来与过去::past-link伪类的创新应用
  • gurobi约束条件使用大全(`model.addConstr()`添加单个约束和`model.addConstrs()`添加多个约束和强不等式约束)
  • 【Gradle】代理配置
  • 视频监控汇聚算法平台训练站车辆类型算法分析车辆类型检测应用方案
  • JUC知识点总结
  • MySQL——单表查询(二)按条件查询(8)使用百分号和下划线通配符进行查询操作
  • Python Word文档安全 - 设置和解除Word文档保护
  • 更改Docker默认存储位置
  • AI搜索产品:秘塔、天工、perplexity、felo、360AI搜索
  • FFmpeg的入门实践系列二(基础知识)
  • Spring Cloud Config 与 Spring Cloud Bus 来实现动态配置文件
  • 网络安全-安全策略初认识
  • 软件测试费用怎么算?湖南软件测评公司简析
  • Visual Studio 和 VSCode 哪个好?
  • linux debian12 离线安装jdk1.8 (解决root和普通用户不能同时拥有java)