c++11 其他特性(一)
c++11还增加了许多有用的特性,比如:
1. 委托构造函数
如果一个类含有很多构造函数,这些构造函数有一些重复的地方,比如:
class A{
public:
A(){};
A(int a){
a_ = a;
};
A(int a, int b){
a_ = a;
b_ = b;
};
A(int a, int b, double c){
a_ = a;
b_ = b;
c_ = c;
};
private:
int a_;
int b_;
double c_;
}
类A的三个构造函数有重复,通过c++11的委托构造函数,可以不用每个构造函数中都写一遍相同的内容:
class A{
public:
A(int a){
a_ = a;
}
A(int a, int b):A(a){
b_ = b;
}
A(int a, int b, double c):A(a, b){
c_ = c;
}
private:
int a_;
int b_;
double c_;
}
需要注意,如果使用了委托构造函数,则不能使用类成员初始化,比如:
class A{
public:
A(int a):a_(a){}; //单独使用类成员初始化,可以
A(int a, int b):A(a), b_(b){}; //同时使用了委托构造函数和类成员初始化,错误!
private:
int a_;
int b_;
}
2. 继承构造函数
如果一个派生类继承自一个基类,如果其构造函数想要使用和基类相同的构造函数,如果构造函数有多个,则在派生类中要写多个构造函数,每个都用基类构造,如下:
class Base{
public:
Base(int a);
Base(int a, int b);
Base(int a, int b, double c);
~Base();
};
class Derived{
public:
Derived(int a):Base(a){};
Derived(int a, int b):Base(a, b){};
Derived(int a, int b, double c):Base(a, b, c){};
};
在c++11中,可以使用继承构造函数来简化这一操作:
class Base{
public:
Base(int a);
Base(int a, int b);
Base(int a, int b, double c);
~Base();
};
class Derived{
public:
using Base::Base; //声明使用基类构造函数
//使用继承构造函数,不用重复写了
};
不只是构造函数,还可以声明其他任何函数来在派生类中使用基类中的函数:
struct Base{
void Func(){
cout << "call in base" << endl;
}
};
struct Derived:Base{
void Func(int a){
cout << "call in derived" << endl;
}
};
int main(){
Derived d;
d.Func(); //编译错误,因为派生类中没有声明 Func()函数,只有 Func(int)函数
return 0;
}; //在c++11中,使用继承函数,改成如下形式即可以正常运行:
struct Derived:Base{
void Func(int a){
cout << "call in derived" << endl;
}
};
3. 原始的字面量
原始字面量可以直接表示字符串的实际含义,因为有些字符串带一些特殊字符,比如在转义字符串中,我们往往要专门处理。如windows路径名:D:\A\B\test.txt"
在c++11中,使用R"xx(string)xx" 来获得括号中的string部分的字符串形式,不需要使用转义字符等附加字符,比如:
string a = R"(D:\A\B\test.txt)"
注意,R"xxx(raw string)xxx",其中原始字符串必须用括号()括起来,括号前后可以加其他字符串,所加的字符串是会被忽略的,而且加的字符串必须在括号两边同时出现.
string str = R"test(D:\A\B\test.txt)";//错误,test只在一边出现
string str = R"test(D:\A\B\test.txt)tt"; //错误,左右两边的字符串不同
string str = R"test(D:\A\B\test.txt)test" //ok
string str = R"(D:\A\B\test.txt)" //ok
4. final或override关键字
c++11中增加了final关键字来限制某个类不能被继承(类似java)或者某个虚函数不能别重写(类似c#中的sealed)。如果修饰函数,final只能修饰虚函数,并且要放到类或者函数的后面。
struct A{
virtual void foo() final; // foo 声明为final的虚函数,不能被重写
void test() final; // 错误,final只能修饰虚函数
};
struct B final{ //B声明为final,表示不能被继承
};
struct C: B{ //错误,B不能被继承
};
c++11中还增加了override关键字确保在派生类中声明的重写函数与基类的虚函数有相同的签名,同时也明确表明将会重写基类的虚函数,还可以防止因疏忽把原来想重写基类的虚函数声明为重载。override关键字要放到方法的后面
struct A{
virtual void func();
};
struct D:A{
void func() override{
};
};
5. 内存对齐
cpu访问内存的时候,起始地址并不是随意的,例如有些cpu访问内存起始地址要是4的倍数,因为内存总线的宽度为32位,每次读写操作都4个字节4个字节进行。如果某个数据在内存中不是字节对齐的,则会在访问的时候比较麻烦,比如4字节的int32类型,没有4字节对齐,则需要访问两次内存才能读到完整的数据。因此,内存对齐可以提高程序的效率。
c++数据内存对齐的含义是,数据在内存中的起始地址是数据size的倍数。c++结构体内存对齐的原则是:结构体内的每个变量都自身对齐,比如int32 4字节对齐,char 1字节对齐;整个结构体按照结构体内的最大size变量的对齐方式对齐,比如
struct{
int a;
char c;
double d;
};
结构体按照最大size的变量对齐,即按照double的8字节对齐。
对于结构体来说,默认的对齐等于其中最大的成员的对齐值。并且,在限定结构体的内存对齐时,同时也限定了结构体内所有成员的内存对齐不能超过结构体本身的内存对齐。
利用alignas指定内存对齐大小
alignas(32) long long a = 0; //指定a为32字节对齐。 alignas可以将内存对齐改大,
//而不能改小,因此,可以有 alignas(32) long long a; 而不能有alignas(1) long long a;
#define XX 1
struct alignas(XX) MyStruct{ //指定为1字节对齐,因为MyStruct内部没有数据,自然为1字节对齐。
//如果内部含有int类型数据,则alignas 只能经对齐方式改大不能改小,故不能为1字节对齐
};
alignas只能将内存对齐改大不能改小,如果要改小,设置内存对齐为1字节对齐,仍然需要使用 #pragma pack(1) .... #pragma pack()
利用alignof和std::alignment_of获取内存对齐大小
alignof 只能返回size_t,即内存对齐的大小,而alignment_of继承自std::integral_constant,拥有 value_type, type和value等成员。
MyStruct xx;
cout << alignof(xx) << endl;
cout << alignof(MyStruct) << endl;
cout << std::alignment_of<MyStruct<::value << std::endl;
内存对齐的类型 std::aligned_storage
aligned_storage可以看成一个内存对齐的缓冲区,原型如下:
template<std::size_t Len, std::size_t Align = /*default-alignment*/>
struct aligned_storage;
Len代表所存储类型的size,Align代表所存储类型的对齐大小 struct A{
int a;
double c;
A(int aa, double cc):a(aa), c(cc){};
};
typedef std::aligned_storage<sizeof<A>, alignof(A)>::type Aligned_A;
int main(){
Aligned_A a, b; //声明一块内存对齐的内存
new (&a)A(10, 20.0); //原地构造函数
return 0;
}
c++11 其他特性(一)的更多相关文章
- C++ 11学习和掌握 ——《深入理解C++ 11:C++11新特性解析和应用》读书笔记(一)
因为偶然的机会,在图书馆看到<深入理解C++ 11:C++11新特性解析和应用>这本书,大致扫下,受益匪浅,就果断借出来,对于其中的部分内容进行详读并亲自编程测试相关代码,也就有了整理写出 ...
- C++11新特性总结 (二)
1. 范围for语句 C++11 引入了一种更为简单的for语句,这种for语句可以很方便的遍历容器或其他序列的所有元素 vector<int> vec = {1,2,3,4,5,6}; ...
- C++11新特性总结 (一)
1. 概述 最近在看C++ Primer5 刚好看到一半,总结一下C++11里面确实加了很多新东西,如果没有任何了解,别说自己写了,看别人写的代码估计都会有些吃力.C++ Primer5是学习C++1 ...
- 【转】C++11常用特性的使用经验总结
出处 http://www.cnblogs.com/feng-sc C++11已经出来很久了,网上也早有很多优秀的C++11新特性的总结文章,在编写本博客之前,博主在工作和学习中学到的关于C++11方 ...
- C++ 11 新特性
C++11新特性: 1.auto 2.nullptr 3.for 4.lambda表达式 5.override ...
- [转载] C++11新特性
C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...
- 在C++98基础上学习C++11新特性
自己一直用的是C++98规范来编程,对于C++11只闻其名却没用过其特性.近期因为工作的需要,需要掌握C++11的一些特性,所以查阅了一些C++11资料.因为自己有C++98的基础,所以从C++98过 ...
- C++11常用特性的使用经验总结
转自:http://www.cnblogs.com/feng-sc C++11已经出来很久了,网上也早有很多优秀的C++11新特性的总结文章,在编写本博客之前,博主在工作和学习中学到的关于C++11方 ...
- [转]C++11常用特性的使用经验总结
转载出处 http://www.cnblogs.com/feng-sc C++11已经出来很久了,网上也早有很多优秀的C++11新特性的总结文章,在编写本博客之前,博主在工作和学习中学到的关于C++1 ...
- C++11新特性——range for
很多编程语言都有range for语法功能,自C++11起,终于将这个重要功能加入C++标准中.range for语句,可以方便的遍历给定序列中的每个元素并对其执行某种操作. 1.基本语法 for(d ...
随机推荐
- 如何快捷输入函数上方的注释代码(Summary)
写完类或函数(注意必须写完,不然出现的信息会不完整)后,在其上方空行输入/**,然后回车,就可以为其添加Summary.
- 基于PowerShell 3.0的web接口测试
对于web接口测试,做一下总结. 接口测试总结 1. 接口url格式:http://www.xxx.com/a/bbb.html: 2. 接口url后面接的参数格式:“?参数名=参数值&参数名 ...
- 2016 ACM/ICPC Asia Regional Qingdao Online HDU5882
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5882 解法:一个点必须出度和入度相同就满足题意,所以加上本身就是判断奇偶性 #include<std ...
- ldataset 与 list 的使用
[WebMethod(Description = @"根据时间查询会议项目[时间格式为:2014-01-01] DateTime StartTime , DateTime Endtime & ...
- C语言第4天循环,流程控制。
C语言第四天 :first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { borde ...
- SqlSever基础 where 与 group by组合起来 处理数据
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...
- Eclipse搭建Android5.0应用开发环境 “ndk-build”:launchingfailed问题解决
Eclipse搭建Android5.0应用开发环境 "ndk-build":launchingfailed问题解决 详细参考http://blog.csdn.net/loongem ...
- MSM8909平台 LED背光的控制
之前齐师兄问我,是不是应该有一个文件记录背光灯的亮度,我说理论上有,但是在哪里我真的还没有见过.只知道在调LCD驱动的时候会调用一个背光控制的函数,传进来一个亮度值就可以配置亮度了,至于这个函数是谁调 ...
- [转]Unity3D协程介绍 以及 使用
作者ChevyRay ,2013年9月28日,snaker7译 原文地址:http://unitypatterns.com/introduction-to-coroutines/ 在Unity中,协 ...
- 【CC评网】2013.第42周 话说时间管理
时间管理 工作几年之后,大家都会有意识的培养时间管理的概念:但如何真正做到位,并持续坚持,并不是一件容易的事: 虽然关注时间管理已有几年,但目前我对于时间的利用并不高效: 理论上的东西就是那些,但真正 ...