c++11还增加了许多有用的特性,比如:

1. 委托构造函数

如果一个类含有很多构造函数,这些构造函数有一些重复的地方,比如:

  1. class A{
  2. public:
  3. A(){};
  4. A(int a){
  5. a_ = a;
  6. };
  7. A(int a, int b){
  8. a_ = a;
  9. b_ = b;
  10. };
  11. A(int a, int b, double c){
  12. a_ = a;
  13. b_ = b;
  14. c_ = c;
  15. };
  16. private:
  17. int a_;
  18. int b_;
  19. double c_;
  20. }

类A的三个构造函数有重复,通过c++11的委托构造函数,可以不用每个构造函数中都写一遍相同的内容:

  1. class A{
  2. public:
  3. A(int a){
  4. a_ = a;
  5. }
  6. A(int a, int b):A(a){
  7. b_ = b;
  8. }
  9. A(int a, int b, double c):A(a, b){
  10. c_ = c;
  11. }
  12. private:
  13. int a_;
  14. int b_;
  15. double c_;
  16. }

需要注意,如果使用了委托构造函数,则不能使用类成员初始化,比如:

  1. class A{
  2. public:
  3. A(int a):a_(a){}; //单独使用类成员初始化,可以
  4. A(int a, int b):A(a), b_(b){}; //同时使用了委托构造函数和类成员初始化,错误!
  5. private:
  6. int a_;
  7. int b_;
  8. }

2. 继承构造函数

如果一个派生类继承自一个基类,如果其构造函数想要使用和基类相同的构造函数,如果构造函数有多个,则在派生类中要写多个构造函数,每个都用基类构造,如下:

  1. class Base{
  2. public:
  3. Base(int a);
  4. Base(int a, int b);
  5. Base(int a, int b, double c);
  6. ~Base();
  7. };
  8. class Derived{
  9. public:
  10. Derived(int a):Base(a){};
  11. Derived(int a, int b):Base(a, b){};
  12. Derived(int a, int b, double c):Base(a, b, c){};
  13. };

在c++11中,可以使用继承构造函数来简化这一操作:

  1. class Base{
  2. public:
  3. Base(int a);
  4. Base(int a, int b);
  5. Base(int a, int b, double c);
  6. ~Base();
  7. };
  8. class Derived{
  9. public:
  10. using Base::Base; //声明使用基类构造函数
  11. //使用继承构造函数,不用重复写了
  12. };

不只是构造函数,还可以声明其他任何函数来在派生类中使用基类中的函数:

  1. struct Base{
  2. void Func(){
  3. cout << "call in base" << endl;
  4. }
  5. };
  6. struct Derived:Base{
  7. void Func(int a){
  8. cout << "call in derived" << endl;
  9. }
  10. };
  11. int main(){
  12. Derived d;
  13. d.Func(); //编译错误,因为派生类中没有声明 Func()函数,只有 Func(int)函数
  14. return 0;
  15. };
  16.  
  17. //在c++11中,使用继承函数,改成如下形式即可以正常运行:
  18. struct Derived:Base{
  19. void Func(int a){
  20. cout << "call in derived" << endl;
  21. }
  22. };

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",其中原始字符串必须用括号()括起来,括号前后可以加其他字符串,所加的字符串是会被忽略的,而且加的字符串必须在括号两边同时出现.

  1. string str = R"test(D:\A\B\test.txt)";//错误,test只在一边出现
  2. string str = R"test(D:\A\B\test.txt)tt"; //错误,左右两边的字符串不同
  3. string str = R"test(D:\A\B\test.txt)test" //ok
  4. string str = R"(D:\A\B\test.txt)" //ok

4. final或override关键字

c++11中增加了final关键字来限制某个类不能被继承(类似java)或者某个虚函数不能别重写(类似c#中的sealed)。如果修饰函数,final只能修饰虚函数,并且要放到类或者函数的后面。

  1. struct A{
  2. virtual void foo() final; // foo 声明为final的虚函数,不能被重写
  3. void test() final; // 错误,final只能修饰虚函数
  4. };
  5. struct B final{ //B声明为final,表示不能被继承
  6. };
  7. struct C: B{ //错误,B不能被继承
  8. };

c++11中还增加了override关键字确保在派生类中声明的重写函数与基类的虚函数有相同的签名,同时也明确表明将会重写基类的虚函数,还可以防止因疏忽把原来想重写基类的虚函数声明为重载。override关键字要放到方法的后面

  1. struct A{
  2. virtual void func();
  3. };
  4. struct D:A{
  5. void func() override{
  6. };
  7. };

5. 内存对齐

cpu访问内存的时候,起始地址并不是随意的,例如有些cpu访问内存起始地址要是4的倍数,因为内存总线的宽度为32位,每次读写操作都4个字节4个字节进行。如果某个数据在内存中不是字节对齐的,则会在访问的时候比较麻烦,比如4字节的int32类型,没有4字节对齐,则需要访问两次内存才能读到完整的数据。因此,内存对齐可以提高程序的效率。 
    c++数据内存对齐的含义是,数据在内存中的起始地址是数据size的倍数。c++结构体内存对齐的原则是:结构体内的每个变量都自身对齐,比如int32 4字节对齐,char 1字节对齐;整个结构体按照结构体内的最大size变量的对齐方式对齐,比如

  1. struct{
  2. int a;
  3. char c;
  4. double d;
  5. };
  6. 结构体按照最大size的变量对齐,即按照double8字节对齐。

对于结构体来说,默认的对齐等于其中最大的成员的对齐值。并且,在限定结构体的内存对齐时,同时也限定了结构体内所有成员的内存对齐不能超过结构体本身的内存对齐。 
利用alignas指定内存对齐大小

  1. alignas(32) long long a = 0; //指定a为32字节对齐。 alignas可以将内存对齐改大,
  2. //而不能改小,因此,可以有 alignas(32) long long a; 而不能有alignas(1) long long a;
  3. #define XX 1
  4. struct alignas(XX) MyStruct{ //指定为1字节对齐,因为MyStruct内部没有数据,自然为1字节对齐。
  5. //如果内部含有int类型数据,则alignas 只能经对齐方式改大不能改小,故不能为1字节对齐
  6. };

alignas只能将内存对齐改大不能改小,如果要改小,设置内存对齐为1字节对齐,仍然需要使用 #pragma pack(1) .... #pragma pack()

利用alignof和std::alignment_of获取内存对齐大小 
     alignof 只能返回size_t,即内存对齐的大小,而alignment_of继承自std::integral_constant,拥有 value_type, type和value等成员。

  1. MyStruct xx;
  2. cout << alignof(xx) << endl;
  3. cout << alignof(MyStruct) << endl;
  4. cout << std::alignment_of<MyStruct<::value << std::endl;

内存对齐的类型 std::aligned_storage 
    aligned_storage可以看成一个内存对齐的缓冲区,原型如下:

  1. template<std::size_t Len, std::size_t Align = /*default-alignment*/>
  2. struct aligned_storage;
  3. Len代表所存储类型的sizeAlign代表所存储类型的对齐大小
  4.  
  5. struct A{
  6. int a;
  7. double c;
  8. A(int aa, double cc):a(aa), c(cc){};
  9. };
  10. typedef std::aligned_storage<sizeof<A>, alignof(A)>::type Aligned_A;
  11. int main(){
  12. Aligned_A a, b; //声明一块内存对齐的内存
  13. new (&a)A(10, 20.0); //原地构造函数
  14. return 0;
  15. }

c++11 其他特性(一)的更多相关文章

  1. C++ 11学习和掌握 ——《深入理解C++ 11:C++11新特性解析和应用》读书笔记(一)

    因为偶然的机会,在图书馆看到<深入理解C++ 11:C++11新特性解析和应用>这本书,大致扫下,受益匪浅,就果断借出来,对于其中的部分内容进行详读并亲自编程测试相关代码,也就有了整理写出 ...

  2. C++11新特性总结 (二)

    1. 范围for语句 C++11 引入了一种更为简单的for语句,这种for语句可以很方便的遍历容器或其他序列的所有元素 vector<int> vec = {1,2,3,4,5,6}; ...

  3. C++11新特性总结 (一)

    1. 概述 最近在看C++ Primer5 刚好看到一半,总结一下C++11里面确实加了很多新东西,如果没有任何了解,别说自己写了,看别人写的代码估计都会有些吃力.C++ Primer5是学习C++1 ...

  4. 【转】C++11常用特性的使用经验总结

    出处 http://www.cnblogs.com/feng-sc C++11已经出来很久了,网上也早有很多优秀的C++11新特性的总结文章,在编写本博客之前,博主在工作和学习中学到的关于C++11方 ...

  5. C++ 11 新特性

    C++11新特性:          1.auto          2.nullptr          3.for          4.lambda表达式          5.override ...

  6. [转载] C++11新特性

    C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...

  7. 在C++98基础上学习C++11新特性

    自己一直用的是C++98规范来编程,对于C++11只闻其名却没用过其特性.近期因为工作的需要,需要掌握C++11的一些特性,所以查阅了一些C++11资料.因为自己有C++98的基础,所以从C++98过 ...

  8. C++11常用特性的使用经验总结

    转自:http://www.cnblogs.com/feng-sc C++11已经出来很久了,网上也早有很多优秀的C++11新特性的总结文章,在编写本博客之前,博主在工作和学习中学到的关于C++11方 ...

  9. [转]C++11常用特性的使用经验总结

    转载出处 http://www.cnblogs.com/feng-sc C++11已经出来很久了,网上也早有很多优秀的C++11新特性的总结文章,在编写本博客之前,博主在工作和学习中学到的关于C++1 ...

  10. C++11新特性——range for

    很多编程语言都有range for语法功能,自C++11起,终于将这个重要功能加入C++标准中.range for语句,可以方便的遍历给定序列中的每个元素并对其执行某种操作. 1.基本语法 for(d ...

随机推荐

  1. Poj(3615),Floyd,最大值中的最小值

    题目链接:http://poj.org/problem?id=3615 题意:大致题意:有N个木桩,和M个木桩对之间的高度差(从x跳到y需要往上跳的高度).从x跳跃到y的路径消耗的体力值是路径中的一个 ...

  2. InheritableThreadLocal原理

    转载:https://github.com/pzxwhc/MineKnowContainer/issues/20 介绍 InheritableThreadLocal 之前,假设对 ThreadLoca ...

  3. c++中函数empty()怎么使用

    string s = "";if (s.empty()){ cout << "字符串为空..";}else{ cout << " ...

  4. EF中限制字段显示长度

    在EF中有些添加的字段 文本显示超多文字,想截取显示又没有截取功能. 怎么办? 我们可以在EF中类的属性中设置 你想限制这个用户名只能有10个字符长度 public String UserName { ...

  5. Java爬虫工程师技能列表

    以下仅仅是自己一些粗浅认识.欢迎补充指正.欢迎进群交流! 掌握一半便能够熟练的开发爬虫玩了.自己正在努力中... 一.技能列表 1.掌握java.尤其编程网络部分:李刚的java基础至少看了三遍以上: ...

  6. flume ng之组件介绍

    1.channel 2.source 3.sink 4.直接读取文件Source,有哪两种方式? 5.Channel有几种方式? 6.Sink在设置存储数据时,数据较多,较少的情况下,该如何处理? F ...

  7. 循环,range,continue 和 break

    1.for循环 用户按照顺序循环可迭代对象中的内容, PS:break.continue li = [11,22,33,44] for item in li:     print item 2.enu ...

  8. Socket重叠IO

    1.为什么到现在才弄懂这个 不知道这个Socket重叠IO这种模型是不是socket IO完成端口的基础,不过我感觉,学习一下这个再去学习socket IO完成端口是比较有好处的. 这个Scoket重 ...

  9. windows下安装zabbix_agents_2.2.0

    下载与解压 下载zabbix_agents_2.2.0 http://www.zabbix.com/downloads/2.2.0/zabbix_agents_2.2.0.win.zip 解压到C盘下 ...

  10. C语言中strdup函数使用方法

    头文件:#include <string.h> 定义函数:char * strdup(const char *s); 函数说明:strdup()会先用malloc()配置与参数s 字符串相 ...