【C++进阶学习】C++中的多态(1)

简介: 【C++进阶学习】C++中的多态(1)

零、前言


C++有五大特性:对象,封装,继承,抽象和多态。而本章则将学习讲解C++中的多态


一、多态的概念和定义


概念:

通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态


示例:买票

普通人买票时,是全价买票;学生买票时,是半价买票;军人买票时是优先买票


定义:

多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为


多态构成条件:


必须通过基类的指针或者引用调用虚函数


被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写


示图:


image.png



二、虚函数


1、概念和定义


  • 虚函数语法:


被virtual修饰的类成员函数称为虚函数


  • 示例:


class Person {
public:
  virtual void BuyTicket() 
  { 
    cout << "买票-全价" << endl; 
  }
};



  • 虚函数重写:


派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数


  • 示例:


class Person {
public:
  virtual void BuyTicket() 
  { 
    cout << "买票-全价" << endl; 
  }
};
class Student : public Person {
public:
  virtual void BuyTicket()
  { 
    cout << "买票-半价" << endl;
  }
};
void Func(Person& p)
{
  p.BuyTicket();
}
int main()
{
  Person ps;
  Student st;
  Func(ps);
  Func(st);
  return 0;
}


2、虚函数重写的特例


  1. 协变


类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象的指针或者引用时,称为协变(基类与派生类虚函数返回值类型不同)


  • 示例:


class A {};
class B : public A {};
class Person {
public:
  virtual A* f() 
  { 
    cout << "virtual A* f()" << endl;
    return new A; 
  }
};
class Student : public Person {
public:
  virtual B* f() 
  { 
    cout << "virtual B* f()" << endl;
    return new B; 
  }
};
void Func(Person& p)
{
  p.f();
}
int main()
{
  Person ps;
  Student st;
  Func(ps);
  Func(st);
  return 0;
}


  1. 派生类虚函数不加virtual


在重写基类虚函数时,派生类的虚函数在不加virtual关键字也可以构成重写


  • 原因:


继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性)


  • 示例:


class Person {
public:
  virtual void BuyTicket()
  {
    cout << "买票-全价" << endl;
  }
};
class Student : public Person {
public:
  //派生类虚函数不加virtual也构成虚函数
  void BuyTicket() 
  { 
    cout << "买票-半价" << endl; 
  }
};
void Func(Person& p)
{
  p.BuyTicket();
}
int main()
{
  Person ps;
  Student st;
  Func(ps);
  Func(st);
  return 0;
}


注意:

该种写法不是很规范,不建议这样使用


如果基类的虚函数不加virtual,派生类的虚函数加virtual,这种情况是不构成虚函数的


析构函数的重写

我们知道,基类指针和引用可以指向基类和派生对象,由此通过指针和引用释放对象时需要实现析构的多态,但基类与派生类析构函数名字不同


为了解决,编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor


示例:


class Person {
public:
  virtual ~Person() 
  { 
    cout << "~Person()" << endl; 
  }
};
class Student : public Person {
public:
  virtual ~Student() 
  { 
    cout << "~Student()" << endl; 
  }
};
//只有派生类Student的析构函数重写了Person的析构函数
//当delete对象调用析构函数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数
int main()
{
  Person* p1 = new Person;
  Person* p2 = new Student;
  delete p1;
  delete p2;
  return 0;
}
相关文章
|
5天前
|
C++ 开发者
C++学习之继承
通过继承,C++可以实现代码重用、扩展类的功能并支持多态性。理解继承的类型、重写与重载、多重继承及其相关问题,对于掌握C++面向对象编程至关重要。希望本文能为您的C++学习和开发提供实用的指导。
37 16
|
24天前
|
算法 网络安全 区块链
2023/11/10学习记录-C/C++对称分组加密DES
本文介绍了对称分组加密的常见算法(如DES、3DES、AES和国密SM4)及其应用场景,包括文件和视频加密、比特币私钥加密、消息和配置项加密及SSL通信加密。文章还详细展示了如何使用异或实现一个简易的对称加密算法,并通过示例代码演示了DES算法在ECB和CBC模式下的加密和解密过程,以及如何封装DES实现CBC和ECB的PKCS7Padding分块填充。
45 4
2023/11/10学习记录-C/C++对称分组加密DES
|
5月前
|
算法 C语言 C++
C++语言学习指南:从新手到高手,一文带你领略系统编程的巅峰技艺!
【8月更文挑战第22天】C++由Bjarne Stroustrup于1985年创立,凭借卓越性能与灵活性,在系统编程、游戏开发等领域占据重要地位。它继承了C语言的高效性,并引入面向对象编程,使代码更模块化易管理。C++支持基本语法如变量声明与控制结构;通过`iostream`库实现输入输出;利用类与对象实现面向对象编程;提供模板增强代码复用性;具备异常处理机制确保程序健壮性;C++11引入现代化特性简化编程;标准模板库(STL)支持高效编程;多线程支持利用多核优势。虽然学习曲线陡峭,但掌握后可开启高性能编程大门。随着新标准如C++20的发展,C++持续演进,提供更多开发可能性。
95 0
|
2月前
|
存储 编译器 数据安全/隐私保护
【C++】多态
多态是面向对象编程中的重要特性,允许通过基类引用调用派生类的具体方法,实现代码的灵活性和扩展性。其核心机制包括虚函数、动态绑定及继承。通过声明虚函数并让派生类重写这些函数,可以在运行时决定具体调用哪个版本的方法。此外,多态还涉及虚函数表(vtable)的使用,其中存储了虚函数的指针,确保调用正确的实现。为了防止资源泄露,基类的析构函数应声明为虚函数。多态的底层实现涉及对象内部的虚函数表指针,指向特定于类的虚函数表,支持动态方法解析。
34 1
|
3月前
|
编译器 C语言 C++
配置C++的学习环境
【10月更文挑战第18天】如果想要学习C++语言,那就需要配置必要的环境和相关的软件,才可以帮助自己更好的掌握语法知识。 一、本地环境设置 如果您想要设置 C++ 语言环境,您需要确保电脑上有以下两款可用的软件,文本编辑器和 C++ 编译器。 二、文本编辑器 通过编辑器创建的文件通常称为源文件,源文件包含程序源代码。 C++ 程序的源文件通常使用扩展名 .cpp、.cp 或 .c。 在开始编程之前,请确保您有一个文本编辑器,且有足够的经验来编写一个计算机程序,然后把它保存在一个文件中,编译并执行它。 Visual Studio Code:虽然它是一个通用的文本编辑器,但它有很多插
|
3月前
|
编译器 C++
C++入门12——详解多态1
C++入门12——详解多态1
57 2
C++入门12——详解多态1
|
3月前
|
C++
C++入门13——详解多态2
C++入门13——详解多态2
94 1
|
3月前
|
Java 编译器 C++
c++学习,和友元函数
本文讨论了C++中的友元函数、继承规则、运算符重载以及内存管理的重要性,并提到了指针在C++中的强大功能和使用时需要注意的问题。
34 1
|
2天前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
32 18
|
2天前
|
存储 编译器 数据安全/隐私保护
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
30 13