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 其他特性(一)的更多相关文章

  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. 【20160924】GOCVHelper 图像增强部分(1)

    图像增强是图像处理的第一步.这里集成了一些实际使用过程中有用的函数.   //读取灰度或彩色图片到灰度     Mat imread2gray(string path){         Mat sr ...

  2. 使用main方法调用http请求本地服务器的某个servlet报错问题

    java.io.IOException: Server returned HTTP response code: 500 for URL: http://localhost:8081/test/myS ...

  3. wpfのuri(让你完全明白wpf的图片加载方式以及URI写法)

    绝对 pack WPF URI pack://application:,,,/是协议:“,,,”是“///”的变体 1.资源文件 — 本地程序集 Uri uri = new Uri("pac ...

  4. dubbo源码之三——dubbo重构

    dubbo版本:2.5.4 转自:http://javatar.iteye.com/blog/1041832

  5. 如何在安装32位Oracle客户端组件的情况下以64位模式运行

    C#使用System.Data.OracleClient连接Oracle数据库.之前在WinXP上正常运行的程序移植到Windows 2008 x64上之后就连不上数据库了,错误信息如下:启动data ...

  6. ProgressDialog 的 使用

    一 . ProgressDialog ProgressDialog是AlertDialog类的一个扩展,可以为一个未定义进度的任务显示一个旋转轮形状的进度动画,或者为一个指定进度的任务显示一个进度条. ...

  7. Til the Cows Come Home(poj 2387 Dijkstra算法(单源最短路径))

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 32824   Accepted: 11098 Description Bes ...

  8. Cheatsheet: 2014 03.01 ~ 03.31

    .NET Should I be concerned about PDB files? async and await -Simplified-Internals Web Performance tr ...

  9. V-rep学习笔记:曲柄摇杆机构

    在ADAMS中创建一个曲柄摇杆机构很方便,但是V-rep中建模就比较麻烦.下面将自己在V-rep中建立曲柄摇杆机构模型的过程记录下来(由于对V-rep不是很熟,可能会有一些错误,只能等以后发现了再改进 ...

  10. LINUX RPM卸载

    1. which httpd /usr/bin/httpd 2.rpm -q -f /usr/bin/httpd name 3.rpm -e name 如果有依赖: rpm -e --allmatch ...