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)之外的都是对象了,所以,不把对象学明白怎么继续往下学习呢? 一.概述 对象是一种复合值,它将很多值(原始 ...
随机推荐
- mysql常用的信息查询函数
mysql常用信息函数 select version(); --当前数据库服务器版本信息 select database(); --当前使用的数据库 select current_user() 或 s ...
- 枚举Enum转换为List,获取枚举的描述
代码: public class EnumberHelper { public static List<EnumberEntity> EnumToList<T>() { Lis ...
- mysql常见错误/usr/local/mysql/bin/mysqld: [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
出现这种情况多数是找不到data目录,还有就是对data目录没有写入权限.
- Java语句
Java的条件语句,循环语句 /* switch语句格式: switch(表达式) { case 值1: 语句体1; break; case 值2: 语句体2; break; ... default: ...
- 查看linux服务器状态常用命令
最近发现大数据技术的一些部署.高可用.集群等和网站的负载均衡.自动化运维.灾备等其实有很多知识都是重合的,要学好linux运维相关,在大数据的研究上也会有所提高.既然工作需要去系统的去学习linux运 ...
- UVa 506 System Dependencies (细节问题)
题意:输入几种指令,让你进行模拟操作,指令如下: DEPEND item1 item2 (item3 ...) 安装item1需要先安装item2(.item3……) INSTALL item1 安装 ...
- CodeForces 687B Remainders Game(数学,最小公倍数)
题意:给定 n 个数,一个数 k,然后你知道一个数 x 取模这个 n 个的是几,最后问你取模 k,是几. 析:首先题意就看了好久,其实并不难,我们只要能从 n 个数的最小公倍数是 k的倍数即可,想想为 ...
- CodeForces 688B Lovely Palindromes (水题回文)
题意:给一个数n,让你找出长度为偶数,并且是第 n 个回文数. 析:你多写几个就知道了,其实就是 n,然后再加上n的逆序,不过n有点大,直接用string 好了. 代码如下: #include < ...
- checkbox数据回显问题
一.问题 在用复选框的时候,最常用的无非就是全选,全不选,数据回显等问题!要做的比较灵活!最近做项目的时候,就遇到这些问题,下面从js和JQueyr两方面解决一下全选,全不选,数据回显的问题. 二.H ...
- Linux 基础教程 39-作业控制
在Linux系统中,作业是由一个或多个关联进程组成的.用户可以运行多个作业并可以在作业间切换.而作业控制则是对作业的行为进行控制,允许用户对作业的前后台的进行切换和终止操作等.作业相关的控制命 ...