c++11的构造函数继承
https://en.cppreference.com/w/cpp/language/using_declaration
在[Inheriting constructors]这一节.
其实叫做"基类的构造函数前置"比较好.
像mystring继承自string类,但仍然是提供字符串功能.new的时候仍旧希望保留旧有的初始化传参方式.这时候在mystring里一一再实现(调用基类)就比较麻烦.
但在c++11之前只能这样.
c++11之前的默认构造方式(淡然c++11之后还是)是,先把各个基类的默认初始化函数调用一遍.然后对派生字段做默认初始化.
c++11之前用户定义的构造函数,可以在初始化列表里调用基类的构造函数,同时可以传参.基类的构造函数仍旧是先调用一遍.
c++11开始,就有了using Base::Base;的写法,当编译器在派生类里找不到相应的构造函数时,就会在这个基类Base里找.在此之后,会调用其它基类的默认构造函数,派生类的字段则是赋值初始化.(这也是c++11之后引入的)
Inheriting constructors
If the using-declaration refers to a constructor of a direct base of the class being defined (e.g. using Base::Base;), all constructors of that base (ignoring member access) are made visible to overload resolution when initializing the derived class.
If overload resolution selects an inherited constructor, it is accessible if it would be accessible when used to construct an object of the corresponding base class: the accessibility of the using-declaration that introduced it is ignored.
If overload resolution selects one of the inherited constructors when initializing an object of such derived class, then the
Basesubobject from which the constructor was inherited is initialized using the inherited constructor, and all other bases and members ofDerivedare initialized as if by the defaulted default constructor (default member initializers are used if provided, otherwise default initialization takes place). The entire initialization is treated as a single function call: initialization of the parameters of the inherited constructor is sequenced-before initialization of any base or member of the derived object.翻译下来大概是:
using Base::Base;的用途:
>派生类初始化时,基类的所有构造函数对overload resolution可见,无视权限修饰符.
>如果基类的某个构造函数被选中,那么先用它初始化那个基类,然后"其它的基类"和"派生字段"被初始化就像使用默认的default 构造函数.(采用提供的default initializers,若用户未提供,则发生默认初始化).
>那个基类的构造函数总是最先被调用.
下面是例子代码:
struct B1 { B1(int, ...) { } };
struct B2 { B2(double) { } };
int get();
struct D1 : B1 {
using B1::B1; // inherits B1(int, ...)
int x;
int y = get();
};
void test() {
D1 d(, , ); // OK: B1 is initialized by calling B1(2, 3, 4),
// then d.x is default-initialized (no initialization is performed),
// then d.y is initialized by calling get()
D1 e; // Error: D1 has no default constructor
}
struct D2 : B2 {
using B2::B2; // inherits B2(double)
B1 b;
};
D2 f(1.0); // error: B1 has no default constructor
As with using-declarations for any other non-static member functions, if an inherited constructor matches the signature of one of the constructors of
Derived, it is hidden from lookup by the version found inDerived. If one of the inherited constructors ofBasehappens to have the signature that matches a copy/move constructor of theDerived, it does not prevent implicit generation ofDerivedcopy/move constructor (which then hides the inherited version, similar tousing operator=).翻译:简单的说,就是using Base:Base之后,派生类可以重载某一个版本来覆盖掉. 基类的copy/move constructor不受这个using的影响,派生类如果没有copy/move constructor,编译器会生成默认的,不会用基类的.
例子代码:
struct B1 { B1(int); };
struct B2 { B2(int); }; struct D2 : B1, B2 {
using B1::B1;
using B2::B2;
D2(int); // OK: D2::D2(int) hides both B1::B1(int) and B2::B2(int)
};
D2 d2(); // calls D2::D2(int)
c++11的构造函数继承的更多相关文章
- C# DateTime的11种构造函数 [Abp 源码分析]十五、自动审计记录 .Net 登陆的时候添加验证码 使用Topshelf开发Windows服务、记录日志 日常杂记——C#验证码 c#_生成图片式验证码 C# 利用SharpZipLib生成压缩包 Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库
C# DateTime的11种构造函数 别的也不多说没直接贴代码 using System; using System.Collections.Generic; using System.Glob ...
- JS继承之借用构造函数继承和组合继承
根据少一点套路,多一点真诚这个原则,继续学习. 借用构造函数继承 在解决原型中包含引用类型值所带来问题的过程中,开发人员开始使用一种叫做借用构造函数(constructor stealing)的技术( ...
- javascript中继承(二)-----借用构造函数继承的个人理解
本人目录如下: 零.寒暄&回顾 一,借用构造函数 二.事件代理 三,call和apply的用法 四.总结 零.寒暄&回顾 上次博客跟大家分享了自己对原型链继承的理解,想看的同学欢迎猛击 ...
- javascript 封装 构造函数继承 非构造函数继承
1 封装 把"属性"(property)和"方法"(method),封装成一个对象,甚至要从原型对象生成一个实例对象 1.1 简单封装:var cat1 = { ...
- js继承之借用构造函数继承
我的上一篇文章介绍了,原型链继承模式.但是单纯的原型链模式并不能很好地实现继承. 一.原型链的缺点 1.1 单纯的原型链继承最大的一个缺点,来自于原型中包含引用类型的值. 本来,我们没有通过原型链实现 ...
- javascript实现继承3种方式: 原型继承、借用构造函数继承、组合继承,模拟extends方法继承
javascript中实现继承的三种方式:原型继承.借用构造函数继承.混合继承: /* js当中的继承 js中 构造函数 原型对象 实力对象的关系: 1 构造函数.prototype = 原型对象 2 ...
- js继承之组合继承(结合原型链继承 和 借用构造函数继承)
在我的前两篇文章中,我们已经介绍了 js 中实现继承的两种模式:原型链继承和借用构造函数继承.这两种模式都存在各自的缺点,所以,我们考虑是否能将这二者结合到一起,从而发挥二者之长.即在继承过程中,既可 ...
- Javascript继承2:创建即继承----构造函数继承
//声明父类 function SuperClass(id){ //值类型公有属性 this.id = id; //引用类型公有属性 this.books = ['Html','Css']; } // ...
- 深入浅出javascript(十二)继承——构造函数继承和组合继承
#题记: 有一水果类,抽象出属性包括:name(水果品种),price(价格),id(ID号).现有两个子类,分别为苹果,桔子,希望继承水果父类. 一.构造函数继承 构造函数继承相当把父类的属性在子类 ...
随机推荐
- JAVA学习笔记--赋值(“=”)
参考来源:<java编程思想(第四版)> 见第三章3.4节 基本数据类型存储了实际的数值,并非指向一个对象的引用,故其赋值,就是直接将一个地方的内容复制到了另一个地方.例如,对基本数据类型 ...
- sublime text 3 快捷操作
快捷键:1.通用 ↑↓← → 上下左右移动光标 Alt 调出菜单 Ctrl + Shift + P 调出命令板(Command Palette) Ctrl + ` 调出控制台 2.编辑 Ctrl + ...
- docker Error response from daemon
docker 在拉取镜像的时候报错 Using default tag: latest Error response from daemon: Get https://registry-1.docke ...
- boost heap
1. using boost::heap::priority_queue #include <boost/heap/priority_queue.hpp> #include <ios ...
- Mybatis原理及源码分析
什么是Mybatis? Mybatis是一个半自动化的持久层框架. Mybatis可以将向PreparedStatement中的输入参数自动进行映射(输入映射),将结果集映射成Java对象(输出映射) ...
- 7.zabbix常用item
zabbix常用item zabbix常用item vfs.file.md5sum[/etc/crontab] {basic:vfs.file.md5sum[/etc/crontab].diff()} ...
- label runat="server"
<label id="lblWhiteIp_Text_Info" runat="server"></label> 后台对应的类型是 pr ...
- error C2664: “ATL::CStringT<BaseType,StringTraits>::Remove”: 不能将参数 1 从“const char [2]”转换为“char”
转自VC错误:http://www.vcerror.com/?p=1395 问题描述: 代码: CString str("asdfafda"); str.Remove(" ...
- mybatis的一些小细节
Mybatis要解决的问题: 1. 将sql语句硬编码到java代码中,如果修改sql语句,需要修改java代码,重新编译.系统可维护性不高. 设想如何解决? 能否将sql单独配置在配置文件中. 2. ...
- RQNOJ PID331 家族
题目描述 若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系. 规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚.如果x,y是 ...