2. C++11 构造函数相关
1. 继承构造函数
派生类如果要使用基类的成员函数,可以通过using声明来完成。
#include <iostream>
using namespace std; class Base {
public:
void func(double f) { cout << "Base: " << f << endl; }
}; class Derived: Base {
public:
using Base::func;
void func(int i) { cout << "Derived: " << i << endl; }
}; int main()
{
Base b;
b.func(4.5); // Base: 4.5
Derived d;
d.func(4.5); // Base: 4.5
d.func(); // Derived: 3
}
如上代码,使用了using声明,声明派生类Derived也使用基类版本的函数func。在C++11中,这个想法被扩展到构造函数上。
class A {
public:
A(int i) {}
A(double d, int i) {}
A(float f, int i, const char* c) {}
}; class B: A {
public:
using A::A; // 继承构造函数
virtual void ExtraInterface() {}
int d=; // 默认值
}; int main()
{
//B b; // 编译报错,不会生成默认的构造函数 B()
B b1();
B b2(2.3, );
B b3(2.3, , "abc");
}
这样使用using A::A 来声明把基类中的构造函数悉数继承到派生类B中。using继承有以下规则:
- 继承构造函数只会初始化基类中的成员变量
- 不能继承基类中的私有构造函数以及私有成员函数
- 派生类如果是从基类中虚继承的,那么不能在派生类中声明继承构造函数
- 一旦使用了继承构造函数,编译器就不会为派生类生成默认构造函数
2. 委派构造函数
如上例,我们在 Info(int) 和 Info(char)的初始化列表的位置调用了“基准版本”的构造函数Info() 。在初始化列表中调用“基准版本”的构造函数为委派构造函数,而被调用的“基准版本”则为目标构造函数。
所谓委派构造,就是指委派函数将构造的任务委派给了目标构造函数来完成的一种类构造方式。委派构造函数不能有初始化列表造成的,即构造函数不能同时“委派”和使用初始化列表,如果委派构造函数需要给成员变量赋初值,只能放在函数体中。
由于初始化列表的初始化方式总是先于构造函数完成的,这样上述初始化显得不够满意,可以改一下使得委派构造函数依然可以在初始化列表中初始化所有成员。
2.1 委派构造函数的应用
应用1:使用构造模板函数产生目标构造函数。
#include <list>
#include <vector>
#include <deque>
using namespace std; class TDConstructed {
template<class T> TDConstructed(T first, T last) : l(first, last) {}
list<int> l; public:
TDConstructed(vector<short> &v) : TDConstructed(v.begin(), v.end()) {}
TDConstructed(deque<int> &d) : TDConstructed(d.begin(), d.end()) {}
};
如上例子,定义了一个构造函数模板。而通过两个委派构造函数的委托,构造函数模板会被实例化。这样TDConstructed类可以很容易的接受多种容器对其进行初始化。委托构造使得构造函数的泛型编程也成为了一种可能。
应用2:异常处理,如果在委派构造函数中使用try的话,那么从目标构造函数产生的异常,都可以在委派构造函数中被捕捉到。
class DCExcept {
public:
DCExcept(double d) try : DCExcept(, d) {
cout << "Run the body." << endl;
// 其他初始化
}
catch (...) {
cout << "caught exception." << endl;
} private:
DCExcept(int i, int d) {
cout << "going to throw!" << endl;
throw ;
} int type;
double data;
}; int main()
{
DCExcept a(1.2);
}
上述代码中,目标构造函数DCExcept(int i, int d)抛出了一个异常,并在委派构造函数DCExcept(double d)进行捕捉。
3. 右值引用
一个左值表达式代表的是对象本身,而右值表达式代表的是对象的值;变量也是左值。可以这么理解:对于一个表达式,凡是对其取地址(&)操作可以成功的都是左值,否则就是右值。
3.1 C++拷贝构造函数问题
拷贝构造函数中为指针成员分配新的内存再进行内容拷贝的做法在C++编程中几乎被视为不可违背的。不过这样能带来一些问题。


3.2 移动构造函数
Test(Test &&t): m_p(t.m_p)
{
cout << "move constructor" << endl;
t.m_p = nullptr;
}
3.3 std::move
int main()
{
Test t1;
// ......
Test t2(t1);// ......
}
2. C++11 构造函数相关的更多相关文章
- C#构造函数相关主题
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- C++11—lambda函数
[1]lambda表达式语法定义 lambda表达式的语法定义如下: [capture] (parameters) mutable ->return-type {statement}; (1) ...
- 21 , CSS 构造模型
1. div 2. 边距 3. 边框 4. 定位 5. 浮动 1 21.1 div 部分(division)---<div>元素,经常以 div 形式引用---是 XHTML 元素,用于 ...
- C++构造函数知识点整理(C++11标准)
引言 构造函数是c++中的一个比较难的语法知识点.编程实践中,由于在很多情况下可以不显示定义构造函数,或者,虽然定义构造函数的方式并不十分适当,但是程序也能正常运行,故而并不是特别引起开发者的重视. ...
- [ACM训练] 算法初级 之 数据结构 之 栈stack+队列queue (基础+进阶+POJ 1338+2442+1442)
再次面对像栈和队列这样的相当基础的数据结构的学习,应该从多个方面,多维度去学习. 首先,这两个数据结构都是比较常用的,在标准库中都有对应的结构能够直接使用,所以第一个阶段应该是先学习直接来使用,下一个 ...
- [java] 深入理解内部类: inner-classes
[java] 深入理解内部类: inner-classes // */ // ]]> [java] 深入理解内部类: inner-classes Table of Contents 1 简介 ...
- C++多线程环境下的构造函数
多线程的环境里,我们总不可避免要使用锁.于是一个常见的场景就是: class ObjectWithLock { private: std::mutex mtx_; SomeResType shared ...
- jQuery extend方法使用及实现
一.jQuery extend方法介绍 jQuery的API手册中,extend方法挂载在jQuery和jQuery.fn两个不同对象上方法,但在jQuery内部代码实现的是相同的,只是功能却不太一样 ...
- 深入学习JavaScript对象
JavaScript中,除了五种原始类型(即数字,字符串,布尔值,null,undefined)之外的都是对象了,所以,不把对象学明白怎么继续往下学习呢? 一.概述 对象是一种复合值,它将很多值(原始 ...
随机推荐
- 自学PHP的野方法
1.基础知识 最早的基础知识仅限于那么一点点的html和css,比牛毛还牛毛的一点点.所以最开始是从immoc上看视频和跟着练习,花了有一个多月,看完一个路径从:零开始学习ThinkPHP框架,由于基 ...
- Mybatis 实用篇(四)返回值类型
Mybatis 实用篇(四)返回值类型 一.返回 List.Map List<User> getUsers(); <select id="getUsers" re ...
- asp.net 4高级程序设计( 第4版)文摘
第一部分 核心概念 第1章 asp.net 简介 第2章 visual studio 第3章 Web窗体 3.2 web窗体处理阶段 页面框架初始化(page.init),用户代码初始化(page.l ...
- (转)centos liveCD liveDVD netinstall minimal DVD1 DVD2 版本区别
LiveCD 和 LiveDVD 是可以直接光盘运行系统,但不能安装,两者差别在于容量大小,dvd包含的软件要多一些. netinstall 是用于网络安装和系统救援的镜像文件. minimal 这个 ...
- oracle 索引的分类
1. B树索引(默认索引,保存讲过排序过的索引列和对应的rowid值) 1)说明: 1.oracle中最常用的索引:B树索引就是一颗二叉树:叶子节点(双向链表)包含索引列和指向表中每个匹配行的ROWI ...
- CentOS6.5中使用 iperf 检测主机间网络带宽
安装方式 # yum install http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm# yum inst ...
- [Erlang32]ibrowse流程及性能测试
1.简介 ibrowse是用erlang写的一个HTTP client.github地址:https://github.com/cmullaparthi/ibrowse 使用方法见项目的readme. ...
- WPF透明窗体不支持缩放解决方案
方案一 WPF中的无边框透明窗体,由于没有边并且透明,窗体无法进行缩放操作,今天来讲解如何解决这个问题. 先说一下思路,我们先手为该窗体添加4个边,4个角用于缩放操作,然后再为他们写事件,完成拖放操作 ...
- Delphi XE7编译安卓程序出错了
昨天编译一个先前可以正常运行的程序,忽然就不能编译了,总是提示这个错误,经过一番排查,终于搞定了,原因:删除了安卓lib引用的JAR和单元文件.如果你也出现这个问题,打开工程全部目录,看一下是否有打小 ...
- 73. 矩阵置零 leetcode JAVA
题目: 给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0.请使用原地算法. 示例 1: 输入: [ [1,1,1], [1,0,1], [1,1,1] ...