【C++】多态的概念和简单介绍、虚函数、虚函数重写、多态构成的条件、重载、重写、重定义

这篇具有很好参考价值的文章主要介绍了【C++】多态的概念和简单介绍、虚函数、虚函数重写、多态构成的条件、重载、重写、重定义。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

多态

1.多态的概念和介绍

  C++中的多态是一种面向对象编程的特性,它允许不同的对象对同一个消息做出不同的响应。 多态性能够提高代码的可复用性和灵活性,使得代码更加模块化和可扩展。

  多态性是通过使用继承和虚函数实现的。 当一个类被声明为虚函数时,它可以被子类重写,并且在运行时根据对象的实际类型来调用相应的函数。这种动态绑定的特性使得程序能够根据不同的对象类型来执行不同的操作。

  简单总结:就是在完成某个行为时,不同的对象会产生出不同的状态。

【C++】多态的概念和简单介绍、虚函数、虚函数重写、多态构成的条件、重载、重写、重定义,C++,c++

             
  通过多态我们可以模拟实现不同种动物的叫声:

#include <iostream>
using namespace std;

// 基类
class Animal {
public:
    virtual void makeSound() {
        cout << "Animal makes sound" << endl;
    }
};

// 派生类
class Cat : public Animal {
public:
    virtual void makeSound() {
        cout << "meows" << endl;
    }
};

class Dog : public Animal {
public:
    virtual void makeSound() {
        cout << "barks" << endl;
    }
};

class Capybara : public Animal {
public:
    virtual void makeSound() {
        cout << "ka~pi~ba~la~" << endl;
    }
};

int main() {
    Animal* animal1 = new Dog();
    Animal* animal2 = new Cat();
    Animal* animal3 = new Capybara();

    animal1->makeSound(); // 调用Dog类的makeSound函数
    animal2->makeSound(); // 调用Cat类的makeSound函数
    animal3->makeSound(); // 调用Capybara类的makeSound函数

    delete animal1;
    delete animal2;
    delete animal3;
        
    return 0;
}

//meows
//barks
//ka~pi~ba~la~

              

2.虚函数

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

  虚函数是为了实现动态绑定和多态性。当基类的指针或引用指向派生类对象时,通过调用虚函数,可以根据对象的实际类型来确定调用哪个函数。这样在运行时才确定函数的调用,而不是在编译时确定。

  虚函数的定义如下:

class Base {
public:
    virtual void function() {
        // 函数的实现
    }
};

  需要注意的是,虚函数可以是纯虚函数,即在基类中只有函数的声明而没有实现。 纯虚函数的定义如下:

  包含纯虚函数的类被称为抽象类,抽象类不能被实例化,只能作为基类来派生其他类。派生类必须重写纯虚函数才能被实例化。

class Base {
public:
    virtual void function() = 0; // 纯虚函数
};

  

  C++对函数重写的要求比较严格,但是有些情况下由于疏忽,可能会导致函数名字母次序写反而无法构成重载,而这种错误在编译期间是不会报出的,只有在程序运行时没有得到预期结果才来debug会得不偿失,所以:C++11提供了override和final两个关键字,可以帮助用户检测是否重写。

2.1final

  final:修饰虚函数,表示该虚函数不能再被重写。

class Car
{
public:
	virtual void Drive() final {}
};

class Benz :public Car
{
public:
	virtual void Drive() {cout << "Benz-舒适" << endl;}
};

2.2override

  override: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错。

class Car{
public:
	virtual void Drive(){}
};

class Benz :public Car {
public:
	virtual void Drive() override {cout << "Benz-舒适" << endl;}
};

              

3.虚函数的重写

  虚函数的重写是指在派生类中重新定义基类中已经声明为虚函数的函数。通过重写虚函数,派生类可以根据自己的需要重新实现该函数,从而覆盖基类中的实现。

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

  下面的代码就构成重写:

// 基类
class Animal {
public:
    virtual void makeSound() {
        cout << "Animal makes sound" << endl;
    }
};

// 派生类
class Cat : public Animal {
public:
    virtual void makeSound() {
        cout << "meows" << endl;
    }
};

【C++】多态的概念和简单介绍、虚函数、虚函数重写、多态构成的条件、重载、重写、重定义,C++,c++

3.1协变

  协变:基类与派生类虚函数返回值类型不同。

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

class A{};
class B : public A {};

class Person {
public:
	virtual A* f() {return new A;}
};

class Student : public Person {
public:
	virtual B* f() {return new B;}
};

3.2析构函数的重写

  析构函数的重写:基类与派生类析构函数的名字不同。

  如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。虽然函数名不相同,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor。

  析构函数可以被重写,其语法与普通函数的重写相同。派生类可以在其定义中重写基类的析构函数,以便在对象销毁时执行特定的清理操作。

  下面是一个示例代码,演示了如何在派生类中重写基类的析构函数:

#include <iostream>

class Base {
public:
    virtual ~Base() {
        std::cout << "Base destructor" << std::endl;
    }
};

class Derived : public Base {
public:
    ~Derived() override {
        std::cout << "Derived destructor" << std::endl;
    }
};

int main() {
    Base* base = new Derived();
    delete base;

    return 0;
}
//Derived destructor
//Base destructor

              

4.多态构成的条件

  多态性的实现需要满足以下条件:

  (1)存在继承关系: 多态性是通过基类和派生类之间的继承关系来实现的。派生类继承了基类的成员函数和虚函数。

  (2)使用基类指针或引用来调用派生类对象: 通过将基类指针或引用指向派生类对象,可以实现多态性。通过基类指针或引用调用虚函数时,实际调用的是派生类中重写的函数。

  (3)基类中存在虚函数:在基类中声明一个虚函数,使得它可以在派生类中被重写。 通过将基类的成员函数声明为虚函数,可以实现动态绑定,即在运行时根据对象的实际类型来确定调用哪个函数。

  对于上面的代码就满足虚函数的重写:

【C++】多态的概念和简单介绍、虚函数、虚函数重写、多态构成的条件、重载、重写、重定义,C++,c++
             
  简单的多态实现的例子:

  Shape类是一个基类,它包含一个虚函数draw。Circle类和Rectangle类分别是Shape类的派生类,它们重写了draw函数。

  在主函数中,我们创建了一个指向Circle对象的Shape指针和一个指向Rectangle对象的Shape指针。当调用shape1->draw()时,由于shape1指向的是Circle对象,所以会调用Circle类的draw函数,输出"Drawing a circle"。

  同样地,当调用shape2->draw()时,由于shape2指向的是Rectangle对象,所以会调用Rectangle类的draw函数,输出"Drawing a rectangle"。

#include <iostream>
using namespace std;

// 基类
class Shape {
public:
    virtual void draw() {
        cout << "Drawing a shape" << endl;
    }
};

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

class Rectangle : public Shape {
public:
    void draw() {
        cout << "Drawing a rectangle" << endl;
    }
};

int main() {
    Shape* shape1 = new Circle();
    Shape* shape2 = new Rectangle();

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

    delete shape1;
    delete shape2;

    return 0;
}

//Drawing a circle
//Drawing a rectangle

  总结多态的构成条件:

  (1)存在继承;

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

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

              

5.重载、重写、重定义

  重载(Overload)、重写(Override)和重定义(Hide)是面向对象编程中的三个概念,用于描述派生类对基类成员的处理方式。

  (1)重载(Overload): 重载是指在同一个作用域内,根据函数名相同但参数列表不同的规则,定义多个具有相同名称但参数不同的函数。 重载函数可以有不同的返回类型,但不能仅通过返回类型的不同来进行重载。在调用重载函数时,编译器会根据函数调用的参数类型和数量来确定调用哪个重载函数。

  (2)重写(Override): 重写是指在派生类中重新定义基类的虚函数。派生类中的重写函数具有相同的函数名、参数列表和返回类型,它们用于替代基类中的虚函数。 在运行时,通过基类指针或引用调用虚函数时,会根据实际对象的类型调用相应的派生类的重写函数。重写函数可以通过使用override关键字来显式地标记。

  (3)重定义(Hide): 重定义是指在派生类中定义一个与基类中的非虚函数同名的函数。 在派生类中的重定义函数与基类中的函数没有关联,它们是完全独立的函数。在运行时,通过基类指针或引用调用函数时,会根据指针或引用的类型调用相应的函数。重定义函数不需要使用特定的关键字进行标记。

【C++】多态的概念和简单介绍、虚函数、虚函数重写、多态构成的条件、重载、重写、重定义,C++,c++

当然多态还有很多的知识点,这里只是对C++多态的部分介绍了😉
如有错误❌望指正,最后祝大家学习进步✊天天开心✨🎉文章来源地址https://www.toymoban.com/news/detail-648514.html

到了这里,关于【C++】多态的概念和简单介绍、虚函数、虚函数重写、多态构成的条件、重载、重写、重定义的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++函数重载的简单介绍

    个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【C++之路】 中华文化博大精深,我们知道在我们的汉语中,每个词语都有着其不同的含义,甚至是一个词语中有多个含义,我们把它称之为一词多义。比如说加油一词

    2023年04月22日
    浏览(14)
  • C++ 学习 ::【基础篇:05】:C++ 函数重载认识及使用、简单介绍:C++ 支持函数重载的原因

    本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段: 基础篇、STL 篇、高阶数据结构与算法篇 ,相关重点内容如下: 基础篇 : 类与对象 (涉及C++的三大特性等); STL 篇 : 学习使用 C++ 提供的 STL 相关库 ; 高阶数据结构与算

    2024年02月06日
    浏览(31)
  • C++八股 | 函数重写(覆盖)

            函数重载也是C++内一个重要板块,面试挖八股时会从 三大特性-多态-虚函数-函数重写(覆盖)这样的形式提问         派生类对基类同名同参函数进行重新修改/重写的过程 基类有virtual虚函数 同名同参函数 基类指针or引用指向派生类对象 如下代码,构成重写

    2023年04月24日
    浏览(17)
  • c++——重写(覆盖),实际上对应的就是虚函数

    重写 是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。

    2024年02月12日
    浏览(10)
  • <c++>虚函数与多态 | 虚函数与纯虚函数 | 多态的实现原理 | 虚析构函数

    🚀 个人简介:CSDN「 博客新星 」TOP 10 , C/C++ 领域新星创作者 💟 作    者: 锡兰_CC ❣️ 📝 专    栏: 从零开始的 c++ 之旅 🌈 若有帮助,还请 关注➕点赞➕收藏 ,不行的话我再努努力💪💪💪 在上一篇文章中,我们介绍了 c++ 中类与对象的继承,继承可以根据一个或

    2023年04月18日
    浏览(12)
  • C++修炼之路之多态---多态的原理(虚函数表)

    目录 一:多态的原理  1.虚函数表  2.原理分析 3.对于虚表存在哪里的探讨 4.对于是不是所有的虚函数都要存进虚函数表的探讨 二:多继承中的虚函数表 三:常见的问答题  接下来的日子会顺顺利利,万事胜意,生活明朗-----------林辞忧  接上篇的多态的介绍后,接下来介绍

    2024年04月26日
    浏览(9)
  • 【C++】虚函数与多态

    多态性是面向对象程序设计的重要特征之一,是指发出同样的消息被不同类型的对象接受时有可能导致完全不同的行为。多态的实现:函数重载、运算符重载、模板、虚函数。 静态绑定:绑定过程出现在编译阶段,在编译期就已经确定要调用的函数。 动态绑定:绑定过程工

    2024年02月10日
    浏览(24)
  • [C++] 多态(上) -- 抽象类、虚函数、虚函数表

    通俗来说,多态就是多种形态, 具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。 举个栗子:比如 买票这个行为: 当 普通人 买票时,是全价买票; 学生 买票时,是半价买票; 军人 买票时是优先买票。 这个例子就是多态,不同身份对应不同的票

    2024年02月04日
    浏览(10)
  • C++中的多态是什么?如何实现多态?解释一下C++中的虚函数和纯虚函数,它们的作用是什么?

    C++中的多态是什么?如何实现多态? 在C++中,多态(Polymorphism)是面向对象编程的三大特性之一,另外两个是封装(Encapsulation)和继承(Inheritance)。多态指的是允许一个接口(或一个父类引用)在多种数据类型上被实现,或者一个接口被多个不同的类以不同的方式实现。

    2024年02月19日
    浏览(22)
  • 【C++】多态 ④ ( 多态实现原理 | C++ 联编概念 | 链接属性 | 内部链接 | 外部链接 | 联编与链接 | 静态联编 | 动态联编 | 联编 与 virtual 关键字 )

    \\\" 联编 \\\" Linkage 指的是 将 程序模块 和 代码 互相关联的过程 , 将不同源文件中的 同名函数 或 变量 进行链接 ; 在 C++ 语言中 , 每个 函数 或 变量 都有一个 链接属性 , 该链接属性决定了该 函数 或 变量 是否可以在其他源文件中使用 ; 联编 是通过 声明函数或变量 的 链接属性

    2024年02月05日
    浏览(15)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包