• c++学习笔记_6


    前言:本笔记所对应的课程为中国大学mooc中北京大学的程序设计与算法(三)C++面向对象程序设计,主要供自己复习使用,且本笔记建立在会使用c和java的基础上,只针对与c和java的不同来写

    多态

    虚函数和多态的基本概念

    1. 虚函数形式:类中成员函数前加virtual关键字的成员函数就是虚函数。

    2. virtual关键字只用在函数声明前,在具体写函数体时不需要写virtual关键字(就像friend一样)

    3. 构造函数和静态成员函数不能是虚函数。(但是析构函数可以)

    4. 多态:这里的多态和java中的不太一样。定义:通过基类指针(或基类引用)去调用基类和派生类中的同名虚函数时,若基类指针引用的是一个基类对象,那么被调用的是基类的虚函数;若基类指针引用的是一个派生类对象,那么被调用的是派生类的虚函数。(而用基类指针调用普通同名函数时,调用的是基类中的函数)

    多态实例

    1. 在非构造函数,非析构函数的成员函数中调用虚函数,是多态。

    实例:

    class Base{
        public:
            void fun1() { fun2(); }
            //这里的fun2()相当于this->fun2(),而this指针代表的是Base类,是基类指针,因此是多态。所以最后的输出结果是derived
            vitural void fun2() { cout << base << endl; }
    };
    
    class Derived : public Base{
        public:
            vitural void fun2() { cout << derived << endl; }
    };
    
    int main(){
        Derived d;
        Base * p = & d;
        p->fun1();
        //输出结果是 derived
        return 0;
    }
    
    1. 派生类中和基类中虚函数同名同参数表的函数,即使不加virtual也自动成为虚函数。
    2. 在构造函数和析构函数中调用虚函数不是多态,调用的是自己类中定义的函数(如果没有定义,则去调用基类中定义的同名函数)

    多态的实现原理

    每一个有虚函数的类(或者有虚函数类的派生类)都有一个虚函数表,该类的任何对象中都有虚函数表的指针,因此有虚函数类的对象的内存大小会多出来四个字节,多出来的这四个字节就是虚函数表的指针。

    虚析构函数、纯析构函数和抽象类

    1. 通过基类的指针delete派生类的对象时,只会调用基类的析构函数。(而程序自然退出时则会先调用派生类的析构函数,再调用基类的析构函数)要想先调用派生类的析构函数,再调用基类的析构函数,需要把基类的析构函数声明为virtual(这样派生类的析构函数也会默认变成虚函数),即可达到目的。
    2. 只要一个类有虚函数,那么就建议将其析构函数写成虚析构函数。

    实例:

    #include <iostream>
    
    using namespace std;
    
    class Son{
    	public:
    		virtual ~Son(){
    			cout << "bye from son" << endl;
    		}
    }; 
    
    class GrandSon:public Son{
    	public:
    		~GrandSon(){
    			cout << "bye form grandson" << endl;
    		}
    };
    
    int main(){
    	GrandSon s;
    	Son * p = & s; 
    	delete p;
    	return 0;
    }
    
    1. 纯虚函数:没有函数体的虚函数
      写法举例:virtual void Print() = 0 ;
    2. 抽象类:包含纯虚函数的类叫做抽象类(用法同java中的抽象类)
    3. 抽象类只能作为基类来派生新类,不能创建抽象类的对象。
    4. 在抽象类的成员函数中可以调用纯虚函数,但是在构造函数或析构函数内部不可以调用纯虚函数。
  • 相关阅读:
    servlet生命周期和线程安全
    如何保证Redis与数据库的数据一致性
    消息队列高可用、幂等性、顺序性、可靠性传输、堆积问题解决
    如何保证消息队列消息的顺序性
    RabbitMQ 如何保证消息不丢失?
    深入理解MySql事务
    MySQL/mariadb知识点总结
    如何实现一个线程安全的单例,前提是不能加锁
    DUBBO原理、应用与面经总结
    SpringBoot中资源初始化加载的几种方式
  • 原文地址:https://www.cnblogs.com/fyunaru/p/11479558.html
Copyright © 2020-2023  润新知