• C++_多态


    C++_多态

    1、多态的引入
    ①人类作为基类,然后有英国人、中国人…
    注意:以下实例执行结果为
    在这里插入图片描述

    #include 
    #include 
    #include 
    
    using namespace std;
    
    class Human {
    public:
    	void eating(void) { cout<<"use hand to eat"<<endl; }
    };
    
    class Englishman : public Human {
    public:
    	void eating(void) { cout<<"use knife to eat"<<endl; }  //覆写
    };
    
    
    class Chinese : public Human {
    public:
    	void eating(void) { cout<<"use chopsticks to eat"<<endl; }  //覆写
    };
    
    void test_eating(Human& h)
    {
    	h.eating();
    }
    
    int main(int argc, char **argv)
    {
    	Human h;
    	Englishman e;
    	Chinese c;
    
    	test_eating(h);
    	test_eating(e);
    	test_eating(c);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    2、上述实例结果显然不是我们想要的
    注意:要分辨(引入虚函数让系统帮我们分辨,关键词virtual)他们是什么人,然后调用他们自己的吃饭方式
    在这里插入图片描述

    #include 
    #include 
    #include 
    
    using namespace std;
    
    class Human {
    private:
    	int a;
    public:
    	virtual void eating(void) { cout<<"use hand to eat"<<endl; }
    };
    
    class Englishman : public Human {
    public:
    	void eating(void) { cout<<"use knife to eat"<<endl; }
    };
    
    
    class Chinese : public Human {
    public:
    	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
    };
    
    void test_eating(Human& h)
    {
    	h.eating();
    }
    
    int main(int argc, char **argv)
    {
    	Human h;
    	Englishman e;
    	Chinese c;
    
    	test_eating(h);
    	test_eating(e);
    	test_eating(c);
    
    	cout<<"sizeof(Human) = "<<sizeof(h)<<endl;
    	cout<<"sizeof(Englishman) = "<<sizeof(e)<<endl;
    	cout<<"sizeof(Chinese) = "<<sizeof(c)<<endl;
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    3、多态机制:静态联编(非虚函数,在编译好时就已经确定好了调用哪一个),动态联编(虚函数,在运行的时候才确定好调用哪一个函数)
    ①动态联编的实现过程:如果类里面有虚函数,那么他的对象里面有一个指针指向虚函数表,然后在调用函数的时候就会通过这个指针找到虚函数表,然后调用里面的虚函数 ,
    ②加入定义虚函数的关键词virtual,空间会变大(多了12字节,就是多的这个指针指向这个虚函数表 )
    在这里插入图片描述

    4、使用多态时有哪些需要注意的
    ①void test_eating(Human& h)或者void test_eating(Human* h)使用指针或是引用来使用对象的时候,才会有多态
    ②void test_eating(h)传值时,无多态
    在这里插入图片描述
    ③只有类的成员函数才能声明为虚函数
    ④静态成员函数不能是虚函数
    ⑤内联函数不能是虚函数
    ⑥构造函数不能是虚函数
    ⑦析构函数一般都声明为虚函数
    ⑧重载函数参数不同,不可以设为虚函数
    ⑨覆写函数参数和返回值相同,可以设为虚函数(返回值有点例外,当返回值是当前对象的指针或引用的时候也可以设为虚函数)

    5、析构函数一般都声明为虚函数
    注意:~Englishman()和 ~Chinese()输出一下结果这样显然析构函数是不对的,
    在这里插入图片描述
    需要将每个类中的析构函数声明为虚函数virtual ~Englishman()和virtual ~Chinese()
    解释:释放派生类后还需要释放派生类的基类
    在这里插入图片描述

    #include 
    #include 
    #include 
    
    using namespace std;
    
    class Human {
    private:
    	int a;
    public:
    	virtual void eating(void) { cout<<"use hand to eat"<<endl; }
    	virtual ~Human() { cout<<"~Human()"<<endl; }
    };
    
    class Englishman : public Human {
    public:
    	void eating(void) { cout<<"use knife to eat"<<endl; }
    	virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
    };
    
    
    class Chinese : public Human {
    public:
    	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
    	virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
    };
    
    void test_eating(Human h)
    {
    	h.eating();
    }
    
    int main(int argc, char **argv)
    {
    	Human* h = new Human;
    	Englishman* e = new Englishman;
    	Chinese* c = new Chinese;
    
    	Human *p[3] = {h, e, c};
    	int i;
    
    	for (i = 0; i < 3; i++)
    	{
    		p[i]->eating();
    		delete p[i];
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    6、覆写函数参数和返回值相同,可以设为虚函数(返回值有点例外,当返回值是当前对象的指针或引用的时候也可以设为虚函数)
    注意:设置为虚函数,参数名和参数一定要一样,返回值也应该要一样(但是可以是当前对象的指针或引用)

    #include 
    #include 
    #include 
    
    using namespace std;
    
    class Human {
    private:
    	int a;
    public:
    	virtual void eating(void) { cout<<"use hand to eat"<<endl; }
    	virtual ~Human() { cout<<"~Human()"<<endl; }
    	virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
    };
    
    class Englishman : public Human {
    public:
    	void eating(void) { cout<<"use knife to eat"<<endl; }
    	virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
    	virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
    };
    
    
    class Chinese : public Human {
    public:
    	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
    	virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
    	virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
    };
    
    void test_eating(Human& h)
    {
    	h.eating();
    }
    
    void test_return(Human& h)
    {
    	h.test();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
  • 相关阅读:
    真正理解 Load Balance
    【Linux】线程池
    C语言--分段函数--switch语句
    Java 注解
    Python-自动化测试面试
    Vue/ Vue 路由配置 (重温 ) 一级 二级 路由配置 及 路由各种方法重定向 (浏览器渲染)
    国内首款研发领域 AI 项目管理工具发布:PingCode AI
    计算机网络:随机访问介质访问控制之令牌传递协议
    GO语言之Goroutine和channel
    Spring Task简单说明
  • 原文地址:https://blog.csdn.net/weixin_50183638/article/details/126291725