C++动态绑定及返回类型协变

C++多态之动态绑定:

 

1、概念:在程序执行期间(非编译期)判断所引用对象的实际类型,根据其实际类型调用相应的方法。

使用virtual关键字修饰类的成员函数时,指明该函数为虚函数,派生类需要重新实现,编译器将实现动态绑定。

2、条件:a)必须是虚函数。  b)通过基类类型的引用或者指针调用虚函数。

 

 

class Base

{

public:

    Base()

    {

       cout<<"Base:: Base()"<<endl;

    }

 

    ~Base()

    {

        cout<<"Base::~Base()"<<endl;

    }

 

    virtual void Test1()

    {

       cout<<"Base:: Test1()"<<endl;

    }

 

    int sum(int a, int b)

    {

        cout<<"Base:: sum =a+b"<<endl;

        return a+b;

    }

};

 

class Derived:public Base

{

public:

    Derived()

    {

        cout<<"Derived::Derived()"<<endl;

    }

   

    ~Derived()

    {

        cout<<"Derived::~Derived()"<<endl;

    }

protected:    //基类为public

    virtual void Test1()

    {

       cout<<"Derived:: Test1()"<<endl;

    }

 

    virtual int sum(int a, int b)

    {

        cout<<"Derived:: sum= a+b"<<endl;

        return a+b;

    }

 

};

 

void FunTest1(Base& b//通过基类的指针或引用访问派生类的成员

{

    b.Test1();

}

 

void FunTest()

{

    Derived d;

    Base b;

 

    Base& pBase = d;

 

    FunTest1(b);

    FunTest1(d);

   

    cout<<"sum = "<<pBase.sum(1,2)<<endl;

}

 

 

 

 

 

当修改了派生类中重写的虚函数与原来的返回值不同,编译器报错。

 

 

故重写(覆盖)要求具有相同的参数和返回值。而这个规则对于协变则会放松。

 

3、协变:

在C++中,只要原来的返回类型是基类类型的指针或引用,新的返回值类型是派生类的指针或引用,覆盖的方法就可以改变返回类型,这样的返回类型称为协变返回类型。

class Base

{

public:

    Base()

    {

       cout<<"Base:: Base()"<<endl;

    }

 

    ~Base()

    {

        cout<<"Base::~Base()"<<endl;

    }

    virtual Base& operator=(const Base& b)

    {

        cout<<"Base::operator=(const Base& b)"<<endl;

        return *this;

    }

 

};

 

class Derived:public Base

{

public:

    Derived()

    {

       cout<<"Derived:: Derived()"<<endl;

    }

   

    ~Derived()

    {

        cout<<"Derived::~Derived()"<<endl;

    }

    virtual Derived& operator=(const Base& b)

    {

        cout<<"Derived::operator=(const Base& b)"<<endl;

        return *this;

    }

 

};

 

 

void FunTest()

{

    Derived d1,d2;

    Base b;

 

    Base& pBase = d1;

    pBase.operator=(d2);

 

}




协变返回类型的优势在于,总是可以在适当程度的抽象层面工作。目前,一般认为,返回值可以协变,参数则不可以。 
  因此,在C++标准的虚函数中,返回值协变,参数不变。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/459465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用ucontext组件实现的coroutine代码分析

coroutine一般翻译过来就是协程&#xff0c;类似于线程可以切换&#xff0c;而跟线程是由操作系统调度器来实现切换不一样&#xff0c;协程由用户程序自己调度进行切换。我以前也看过协程相关的内容&#xff0c;但没有自己去实现过。最近搞OpenStack&#xff0c;OpenStack各个模…

C++模板剖析:函数模板、类模板解析

C中关于模板&泛型编程问题&#xff1a; 问题引入&#xff1a;何编写一个通用加法函数&#xff1f; &#xff08;1&#xff09;使用函数重载&#xff0c;针对每个所需相同行为的不同类型重新实现它 int Add(const int &_iLeft, const int&_iRight) { return (_iL…

Android Studio 1.1的安装和遇到的坑

Google的Android Studio 出1.0稳定版本也有很久的时间了&#xff0c;一直喜欢Jetbrains公司的IDE&#xff0c;不同语言的IDE操作习惯都比较统一。 而Android Studio 是基于IntelliJ IDEA的社区版开发的 &#xff0c;怎么也要尝尝鲜才行。 今天安装了下&#xff0c;被几个小坑卡…

Linux:Access time、 Modify time 、Change time 和 find 命令使用解析

一、Access time 、Modify time 、Change time 1、含义&#xff1a; Access&#xff1a;是指“访问时间” 对于文件&#xff0c;用编辑器打开file&#xff0c;或使用cat more less grep sed 等等命令读取文件内容&#xff0c;以及使用file cp命令操作文件&#xff0c;或执行…

[HAOI2015]T2

【题目描述】 有一棵点数为N的树&#xff0c;以点1为根&#xff0c;且树点有边权。然后有M个操作&#xff0c;分为三种&#xff1a; 操作1&#xff1a;把某个节点x的点权增加a。 操作2&#xff1a;把某个节点x为根的子树中所有点的点权都增加a。 操作3&#xff1a;询问某个节点…

BestCoder Round #39 解题报告

现场只做出前三题w 不过不管怎样这既是第一次认真打BC 又是第一次体验用在线编译器调代码 订正最后一题花了今天一整个下午&#xff08;呜呜 收获还是比较大的^_^ Delete wld有n个数(a1,a2,...,an)&#xff0c;他希望进行k次删除一个数的操作&#xff0c;使得最后剩下的n−k个数…

linux :vim 实现命令行下输出进度条

1、 进度条原理&#xff1a; 进度条的的动态增长是利用人的视觉短暂停留效果的&#xff0c;不断从输出缓冲区刷新出相同的内容&#xff0c;在肉眼看来进度条在不断的增长。 在显示器上先输出[# ][%1] 刷新一次之后&#xff0c; …

***jquery选择器 之 获取父级元素、同级元素、子元素

一、获取父级元素1、 parent([expr]): 获取指定元素的所有父级元素 <div id"par_div"><a id"href_fir" href"#">href_fir</a><a id"href_sec" href"#">href_sec</a><a id"href_thr&q…

Sql Server字符串函数

字符串函数用于对字符和二进制字符进行各种操作 1.ASCII()函数 ASCII(character_expression)函数用于返回字符串表达式中最左侧的ASCII代码值。参数character_expression必须是一个char或varchar类型的字符串表达式。 eg: select ASCII(s),ASCII(sql),ASCII(1);执行结果如图:字…

linux 编辑器vim配置

1、 基本配置 对vim进行配置的目的&#xff1a; 进行vim配置&#xff0c;可以让我们在后续敲代码更加方便。按F5可以直接编译并执行C、C代码以及执行shell脚本&#xff1b;按“F8”可进行C、C代码的调试&#xff1b;“Ctrl A”为全选并复制快捷键&#xff0c;方便复…

Java从入门到精通——数据库篇Mongo DB GridFS文件系统

一、概述GridFS是MongoDB的一种存储机制&#xff0c;用来存储大型二进制文件。优点&#xff1a;1.使用GridFS能够简化你的栈。如果已经在使用MongoDB&#xff0c;那么可以使用GridFS来代替独立的文件存储工具2.GridFS会自动平衡已有的复制或者为MongoDB设置的自动分片&#xff…

centos 7上ambari安装试用

2019独角兽企业重金招聘Python工程师标准>>> 1、有三台centos7&#xff0c;名字分别是ws11.localdomain, ws12.localdomain, ws13.localdomain。配置epel源(安装epel-release)。 2、配置root用户ssh无密码访问。 3、安装ntp对时服务。 4、关闭防火墙。centos7下使…

进程管理—进程描述符(task_struct)

本文章转载自&#xff1a;http://blog.csdn.net/qq_26768741/article/details/54348586?locationNum4&fps1 前言 当把一个程序加载到内存当中&#xff0c;此时&#xff0c;这个时候就有了进程&#xff0c;关于进程&#xff0c;有一个相关的叫做进程控制块&#xff08;PCB&…

如何使用emacs编写c语言程序,并编译运行

vi和emacs被分别被称为编辑器之神和神之编辑器。vi的入门精通都很难&#xff0c;emacs入门容易&#xff0c;精通难&#xff1b;vi使用起来不停地切换模式&#xff0c;而emacs则不停地ctrl&#xff0c;meta等组合键。因此&#xff0c;高德纳大师说操作Emacs&#xff0c;就像弹奏…

jQuery 鼠标滚轮插件应用 mousewheel

jQuery Mousewheel Plugin,用于添加跨浏览器的鼠标滚轮支持。 mousewheel事件的处理函数有一点小小的变化&#xff0c;它除了第一个参数event 外&#xff0c;还接收到第二个参数delta。 通过参数delta可以获取鼠标滚轮的方向和速度。 如果delta的值是负的即-1&#xff0c;那么滚…

操作系统中常见的进程调度算法

一、调度与调度算法 调度&#xff1a;操作系统管理了系统的有限资源&#xff0c;当有多个进程&#xff08;或多个进程发出的请求&#xff09;要使用这些资源时&#xff0c;因为资源的有限性&#xff0c;必须按照一定的原则选择进程&#xff08;请求&#xff09;来占用资源。这…

大规模快速发展

Jez Humble在 GOTO Berlin 2015会议上讨论了限制大规模快速发展的组织障碍&#xff0c;并提到了如何解决这些障碍。InfoQ对他进行了采访&#xff0c;主要关于我们如何专注于价值而不是成本&#xff0c;为什么对工件的共识非常的有价值&#xff0c;当你不知道客户需要的特性时就…

粘滞位 File文件内容

t权限&#xff08;粘滞位)&#xff1a; 是‘不可删除’权限&#xff0c;就是说即使某用户拥有这个文件的rwx权限&#xff0c;可以随意修改文件内容&#xff0c;但是就是不能删除&#xff0c;甚至不能修改文件名&#xff0c;只有root才行。t权限也可以直接用 chmod ot/at fil…

hdu 3864 素数分解

题意&#xff1a;求n是否只有4个因子&#xff0c;如果是就输出除1外的所有因子。 模板题&#xff0c;就不排版了 1 #include<cstdio>2 #include<iostream>3 #include<algorithm>4 #include<cstring>5 #include<cmath>6 #include<queue>7 #…