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. JAVA基础知识之JVM-——类加载器

    类加载器负责将.class文件加载到内存,并为其创建java.lang.Class对象,这个对象就代表这个类. 在Java中,通过包名+类名来唯一标识一个类,而在JVM中,要用 类加载器实例+包名+类 ...

  2. noi 7627 鸡蛋的硬度

    题目链接:http://noi.openjudge.cn/ch0206/7627/ 题目讲的二分其实是一个误导, d(i,j),表示当前最优策略时,最坏的情况下: 有 J 个鸡蛋,I 个可以怀疑的楼层 ...

  3. 基于@AspectJ和schema的aop(一)

    在前面我们使用Pointcut和Advice描述切点和增强, 并使用Advisor整合两者描述切面.@AspectJ使用注解来描述切点和增强.两者使用的方式不同, 但是在本质上都是一样的. 我们还是用 ...

  4. uva 10090 Marbles

    Problem F Marbles Input: standard input Output: standard output I have some (say, n) marbles (small ...

  5. hdu 2837 坑题。

    Calculation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. D3D 模板缓存的创建过程

    下面是我对模板缓存创建的理解: 1. 模板缓存是和深度缓存一起被创建的,将深度缓存的一部分作为模板缓存使用. 深度缓存和模板缓存是在Direct3D初始化时创建的,D3DPRESENT_PARAMET ...

  7. VC++ 使用WebBrowser控件中html文件以资源形式加载

    . . . . //加载资源文件中的HTML,IDR_HTML1就是HTML文件在资源文件中的ID wchar_t self_path[MAX_PATH] = { }; GetModuleFileNa ...

  8. BZOJ 2666: [cqoi2012]组装

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2666 题意:n种零件,m个位置,每个位置有一种零件.求一个位置x,使得cost(1 ...

  9. Windows安装Python包下载工具pip遇到的问题

    到Python的官网下载get-pip.py文件,然后按照说明进行安装. 在安装过程中,我遇到以下问题: cmd的codepage引起的编码错误,提示65001编码错误,通过chcp 936切换到默认 ...

  10. Create Stacked Canvas to Scroll Horizontal Tabular Data Blocks In Oracle Forms

    In this tutorial you will learn to create horizontal scrollable tabular or detail data block by usin ...