c++stl笔记

cc my.c precious.c
编译部分: cc my.c precious.o

cc usimgmath.c -lm //-lm使用库函数
g++ spify.cxx -g++
cin.get()读取下一次击键
所有头文件都应该使用 #define 防止头文件被多重包含, 命名格式当是: H
例如, 项目 foo 中的头文件 foo/src/bar/baz.h
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_

#endif // FOO_BAR_BAZ_H_

尽可能地避免使用前置声明。使用 #include 包含需要的头文件即可。所谓「前置声明」(forward declaration)是类、函数和模板的纯粹声明,没伴随着其定义.尽量避免前置声明那些定义在其他项目中的实体.? 函数:总是使用 #include.? 类模板:优先使用 #include.
#include 的路径及顺序:
使用标准的头文件包含顺序可增强可读性, 避免隐藏依赖: C 库, C++ 库, 其他库的 .h, 本项目内的 .h.
又如, dir/foo.cc 的主要作用是实现或测试 dir2/foo2.h 的功能, foo.cc 中包含头文件的次序如下:

  1. dir2/foo2.h (优先位置, 详情如下)
  2. C 系统文件
  3. C++ 系统文件
  4. 其他库的 .h 文件
  5. 本项目内 .h 文件
    这种优先的顺序排序保证当 dir2/foo2.h 遗漏某些必要的库时, dir/foo.cc 或 dir/foo_test.cc 的构建会立刻中止。
    前置声明的类是不完全类型(incomplete type),我们只能定义指向该类型的指针或引用,或者声明(但不
    能定义)以不完全类型作为参数或者返回类型的函数。类内部的函数一般会自动内联。所以某函数一旦不需要内联,其定义就不要再放在头文件里,而是放到对应的 .cc 文件里。这样可以保持头文件的类相当精炼,也很好地贯彻了声明与定义分离的原则。
    ----------------
    举例来说, google-awesome-project/src/foo/internal/fooserver.cc 的包含次序如下:
    #include “foo/public/fooserver.h” // 优先位置
    #include <sys/types.h>
    #include <unistd.h>
    #include <hash_map>
    #include
    #include “base/basictypes.h”
    #include “base/commandlineflags.h”
    #include “foo/public/bar.h”
    --------------------
    // .h 文件
    namespace mynamespace {
    // 所有声明都置于命名空间中
    // 注意不要使用缩进
    class MyClass {
    public:

    void Foo();
    };
    } // namespace mynamespace
    // .cc 文件
    namespace mynamespace {
    // 函数定义都置于命名空间中
    void MyClass::Foo() {

    }
    } // namespace mynamespace

如果你必须定义非成员函数, 又只是在 .cc 文件中使用它, 可使用匿名 2.1. 命名空间 或 static 链接关键字
(如 static int Foo() {…}) 限定其作用域.

int i = g(); // 好——初始化时声明
vector v = {1, 2}; // 好——v 一开始就初始化
while (const char* p = strchr(str, ‘/’)) str = p + 1;

不要在头文件中使用 命名空间别名 除非显式标记内部命名空间使用。因为任何在头文件中引入的命名空间都会
成为公开 API 的一部分。namespace baz = ::foo::bar::baz;
将非成员函数放在命名空间内可避免污染全局作用域.
将函数变量尽可能置于最小作用域内, 并在变量声明时进行初始化. int i = g(); // 好——初始化时声明
vector v = {1, 2}; // 好——v 一开始就初始化
禁止定义静态储存周期非 POD 变量,禁止使用含有副作用的函数初始化 POD 全局变量,因为多编译单元中的静态变量执行时的构造和析构
顺序是未明确的,这将导致代码的不可移植。
禁止定义静态储存周期非 POD 变量,禁止使用含有副作用的函数初始化 POD 全局变量,因为多编译单元中的静态变量执行时的构造和析构
顺序是未明确的,这将导致代码的不可移植。
改善以上析构问题的办法之一是用 quick_exit() 来代替 exit() 并中断程序。它们的不同之处是前者不会执行任何析构,
也不会执行 atexit() 所绑定的任何 handlers. 如果您想在执行 quick_exit()来中断时执行某 handler(比如刷新
log),您可以把它绑定到 _at_quick_exit(). 如果您想在 exit() 和 quick_exit() 都用上该 handler, 都绑定上去。
综 上 所 述 , 我 们 只 允 许 POD 类 型 的 静 态 变 量 , 即 完 全 禁 用 vector ( 使 用 C 数 组 替 代 ) 和 string ( 使
用 const char [])。
所有单参数构造函数都必须是显式的.在类定义中, 将关键字 explicit 加到单参数构造函数前: explicit Foo(string name);
为了能作为 STL 容器的值, 你可能有使类可拷贝的冲动. 在大多数类似的情况下, 真正该做的是把对象的 指针 放到
STL 容器中. 可以考虑使用 std::tr1::shared_ptr.
仅当只有数据时使用结构,其它一概使用class;

禁用拷贝构造函数,把拷贝和赋值构造函数声明为私有的,则禁用;因为大部分类不需要拷贝构造
作为STL容器的值,基本上是std::tr1::shared_ptr;
所有继承必须是 public 的. 如果你想使用私有继承, 你应该替换成把基类的实例作为成员对象的方式.必要的话, 析构函数声明为 virtual. 数据成员在任何情况下都必须是私有的.对于重载的虚函数或虚析构函数, 使用 override, 或 (较不常用的) final 关键字显式地进行标记. 在声明重载 时 , 请 使用 override, final 或 virtual 的其中之一进行标记.

接口是指满足特定条件的类, 这些类以 Interface 为后缀 (不强制).

C++ 允许用户通过使用 operator 关键字 对内建运算符进行重载定义 , 只要其中一个参数是用户定义的类型. operator 关键字还允许用户使用 operator"" 定义新的字面运算符, 并且定义类型转换函数, 例如operator bool().只有在意义明显, 不会出现奇怪的行为并且与对应的内建运算符的行为一致时才定义重载运算符.
声明次序: public -> protected -> private;
函数体尽量短小, 紧凑, 功能单一; 函数的参数顺序为: 输入参数在先, 后跟输出参数.
对于虚函数, 不允许使用缺省参数, 因为在虚函数中缺省参数不一定能正常工作. 如果在每个调用点缺省参数的值都有可能不同, 在这种情况下缺省函数也不允许使用. 只有在常规写法 (返回类型前置) 不便于书写或不便于阅读时使用返回类型后置语法.
对于虚函数, 不允许使用缺省参数, 因为在虚函数中缺省参数不一定能正常工作. 如果在每个调用点缺省参数的值都有可能不同, 在这种情况下缺省函数也不允许使用. auto foo(int x) -> int;
动态分配出的对象最好有单一且固定的所有主, 并通过智能指针传递所有权.智能指针是一个通过重载 * 和 -> 运算符以表现得如指针一样的类. 智能指针类型被用来自动化所有权的登记工作, 来确保执行销毁义务到位.
指针语义可要比值语义复杂得许多了, 特别是在 API 里:这时不光要操心所有权, 还要顾及别名, 生命周期, 可变性以及其它大大小小的问题.
所有按引用传递的参数必须加上 const.函数参数列表中, 所有引用参数都必须是 const: 输入参数是值参或 const 引用, 输出参数为指针. 输入参数可以是 const指针, 但决不能是 非 const 的引用参数, 除非用于交换,比如 swap().
右值引用是一种只能绑定到临时对象的引用的一种, 其语法与传统的引用语法相似. 例如, void f(string&& s); 声明了一个其参数是一个字符串的右值引用的函数.如果 v1 是一个 vector, 则 auto v2(std::move(v1)) 将很可能不再进行大量的数据复制而只是简单地进行指针操作, 在某些情况下这将带来大幅度的性能提升.

bool Base::Equal(Base* other) = 0;
bool Derived::Equal(Base* other) {
Derived* that = dynamic_cast<Derived*>(other);
if (that == NULL)
return false;

}
RTTI 有合理的用途但是容易被滥用, 因此在使用时请务必注意. 在单元测试中可以使用 RTTI, 但是在其他代码中请尽量避免. 尤其是在新代码中, 使用 RTTI 前务必三思.
不要使用 C 风格类型转换. 而应该使用 C++ 风格.用 static_cast 替代 C 风格的值转换, 或某个类指针需要明确的向上转换为父类指针时.
用 const_cast 去掉 const 限定符.用 reinterpret_cast 指针类型和整型或其它指针之间进行不安全的相互转换. 仅在你对所做一切了然于心
时使用.至于 dynamic_cast 运行时类型识别.测试代码以外不要使用. 除非是单元测试, 如果你需要在运行时确定类型信息, 说明有 设计缺陷.
类型:
int64_t 或 uint64_t. int16_t, uint32_t, int64_t 只使用 int. 在合适的情况下, 推荐使用标准类型如 size_t 和ptrdiff_t.
不要使用 uint32_t 等无符号整型, 除非你是在表示一个位组而不是一个数值, 或是你需要定义二进制补码溢出.尤其是不要为了指出数值永不会为负, 而使用无符号类型. 相反, 你应该使用断言来保护数据.
整数用 0, 实数用 0.0, 指针用 nullptr 或 NULL, 字符 (串) 用 ‘\0’
尽可能用 sizeof(varname) 代替 sizeof(type).
用 auto 绕过烦琐的类型名,只要可读性好就继续用,别用在局部变量之外的地方。
auto 只能用在局部变量里用。别用在文件作用域变量,命名空间作用域变量和类数据成员里。永远别列表初始化 auto 变量
适当使用 lambda 表达式。别用默认 lambda 捕获,所有捕获都要显式写出来。Lambda 表达式是创建匿名函数对象的一种简易途径,常用于把函数当参数传。打比方,比起 [=](int x) {return x + n;}, 您该写成 [n](int x) {return x + n;} 才对,这样读者也好一眼看出 n 是被捕获的值
不要使用复杂的模板编……

我们强烈建议你在任何可能的情况下都要使用 const. 此外有时改用 C++11 推出的 constexpr 更好。
因此, 使用断言来指出变量为非负数, 而不是使用无符号型!

命名风格:
int num_errors; // Good.
int num_completed_connections; // Good.
一般来说, 函数名的每个单词首字母大写 (即 “驼峰变量名” 或 “帕斯卡变量名”), 没有下划线. 对于首字母缩写的单词,
更倾向于将它们视作一个单词进行首字母大写 (例如, 写作 StartRpc() 而非 StartRPC()).
AddTableEntry()
DeleteUrl()
OpenFileOrDie()

命名空间内容不缩进.
if (b) { // if 条件语句和循环语句关键字后均有空格.
} else { // else 前后有空格
}
其实我主张指针/地址操作符与变量名紧邻,int *a, b, 新手会误以为前者的 b 是 int * 变量, 但后
者就不一样了, 高下立判.
不要使用 #pragma once; 而应该使用 Google 的头文件保护规则.
通常为了利用头文件预编译, 每个每个源文件的开头都会包含一个名为 StdAfx.h 或 precompile.h 的文件.

char, wchar_t,short, int, long, longlong;
#include INT_MAX, LONG_MAX
sizeof n 即是按字节算;4字节;
char16_t,char32_t;
强制类型转换:(long)thorn 强制类型转换不会修改thorn变量本身,而是创建一个新的,指

定的类型的值,可以在表达式中使用这个值;
static (thorn) ; static_cast<>可用于将值从一种数值类型转换为另一种数值类型


(int)3.14; 新语法; int(3.14); 新语法 ;  static_cast (1.03e6); 新语法

si{ sizeof sz / sizeof(int) }; 注意写法,尽量是sizeof 变量名,如果不是,则是变

量名不加括号,而类型加括号;
"s"实际上表示瓣是字符串所在的内存地址;
cin.get(name,size);//面向行的输入;不能跨换行符;
cin.getline(name,size);
cin.clear();

#include 中有getlin(); std::getline(std::cin,str);
R"(…)"; //原始字符串以R"(内容 )";
union one4all 共用体每次只能存储一个值;

长度固定的数组可以用array;
#include
array<int,5> ai{12,3,4,5,6};

检测到EOF后,cin将两位eof,failbit都设置为1,可以通过成员eof()查看eofbit; eof

(),fail()方法报告最近读取的结果;
ifstream inFile; //从文件读 重载 >> 用于把文件内容读入变量; infile >> str;

从文件读内容到str;
ofstream outfile // outfile outfile << "good "; 将good 写入文件
infile.open() .good();.eof().fail();
不要试图使用方括号表示法来传递数组长度,为将数组类型和元素数量告诉数组处理函数;
函数指针: double (pf) (int); //即把函数名用加上,但是*又不能和返回值一起,所

以加括号;好记就是加*;
typedef double real; // 用real代替double;
使用const的好处:1.避免无意修改; 2.使用const使函数能够处理const和非const实参,

否则只能接收非const数据;使用const引用使函数能够正确生成临时变量;//还有传言,

const只读变量单片机速度更快;
右值引用: double &&rref = std::sqrt(36);
template
void swap(){…}
具体化 template<> void swap (job&,job&);
在调用时声明参数类型,叫显示实例化: swap(x,y); // 显示实例化;
decltype (x) y; //声明类型;语法:decltype() 得到的是一个类型;类型后面必跟变量名


decltype()里面如果是函数,则类型为返回值类型,通过原型查看的,并不会调用;
全语法:
template<class T1,class T2>
auto gt(T1 x,T2 y)-> decltype(x+y){…return x+y;}

变量的单定义规则:变量只能定义一次,C++提供两种变量声明,一种定义声明,简称定义

,分配空间,另一种引用声明,简称声明;不分配空间,因为它引用己有的变量;引用声明

使用extern,并不进行初始化;

extern double warming; 使用外部的warming变量;声明语法
extern double warming = 3.14; //定义语法,因为初始化了;
在外面文件定义的函数,一定要向前引用声明;加不加extern都没有所谓;比哪在外面文件

定义的函数,前面一定要有函数原型,然后再调用;
关键字volatile表明,即使程序代码没有对内存单元进行修改,其值也可能发生变化;
现在回到mutable,即使结构变量为const,其某个成员也可以被修改;
const int* p_san = &grop; //放在最前面,禁止修改值;
int * const p_snak = &grop; //不放在最前面,禁止修改指针;
传递类对象参数的标准方式是按引用传递;
typedef decltype(x+y) xytype; // decltype推断出实际的类型,然后用xytype代替;
语言链接性: extern “C” void spiff(); //指出是按C标准调用函数;
new不到合适的内存量时,引发std::bad_alloc异常;
定位new语法 p2 = new(buffer) int[20]; //在buffer内存地址中分配20个int数组;
名字空间不能位于代码块内;
对于文件间的共享变量,应在一个文件中包含其定义声明(无需extern),并在其他文件中包

含引用声明(使用extern)且不初始化;
this指针指向调用对象,如果方法需要引用整个调用对象,则可以使用this.可以将this作

为调用对象的别名来完成前面的方法定义;
ios_base::fmtflags orig = cout.setf(ios_base::fixed,ios_base::floatfield);
std::streamsize prec = cout.precision(3);
cout.set(orig,ios_base::floatfield);
cout.precision(prec);
声明类只是描述对象的形式,并没有创建对象;
class Bakery {
private :
enum {Months = 12}; //另一种: static const int Months = 12;

double const[Months}; 

创建友元函数第一步: 将原型放在类声明中,然后原型前加friend; //不是成员函数;但

能访问私有;
成员版的重载参数少一个,因为其中一个操作数是被隐式的转递调用对象;
显示调用:
T1 = T2.operator+(T3); T1 = operator+(T2,T3);

类的自动转换和强制类型转换:只有接受一个参数的构造函数才能作为转换函数;explicit

就是用于关掉这种特性的;
转换成员函数:   operator int() const; //不能有返回值和参数;原因:返回值一

定是int.参数本来就有,就是要转换的对象;C++11允许转换函数变显示: explicit

opearator int() const;
一开始,就声明全局变量:
int StringBad::num_strings = 0;
c++11提供另外两个特殊成员函数;移动构造函数,移动赋值运算符;
如果被返回的对象是被调用函数中的局部变量,则不应该按引用方式返回,因为局部对象将

析构,在这种情况下,应该返回对象而不是引用;
复制构造函数的原型: className(const className&); //注意加了const;
成员初始化列表语法: classname::classname(int n,int m) : mem(n),men2(0),men3

(n*m+2){…}
c++11允许类内初始化;即在类定义中进行初始化;这与使用成员初始化列表等价;
派生类对象过期时,程序首先调用派生类析构函数,然后再调用基类析构函数;
如果返回类型是基类引用或指针,则可以修改为指向派生类的引用或指针,这种特性为返回

类型协变(covariance of return type),因为允许返回类型随类类型的变化而变化;
抽象类: void Move(int nx,my) = 0;
valarray类用于处理数值;它支持诸如将数组中所有元素值加或在数组中找最大最小值操作

;valarray vi;
私有继承,基类的公有成员和保护成员都将成为派生类的私有成员;基类方法将不会成为派

生对象公有接口的一部分,只是派生类成员可以用它;
虚基类: class Singer: virtual public worker; class Waiter: virutal public

worker //钻石继承最顶端,二个类都有的那个公共虚基类
调用虚基类的方法: Singer::show(); Waiter::show();
类模板:
template
class Stack{ …Type items; //里面不变,只是增加了Type这个模板变量类型;
然后实现的时候,注意: template Stack::stack(){…}
每个实现的成员函数,要加template以及类名要指定Stack::Stack; 要指明所属;
template<class T,int n>
class ArrayTp{ T ar[n]; //定义
实例化: ArrayTp<int,5> tp;
template <class T1, class T2 = int> class ToP{…}; //模板带默认参数;
显示实例化:template class ArrayTp<string,100>; //显示的根据模板类生成一个类,类

己经生成,类模板并不是强制生成所有类的,只会在需要的时候生成类;这时显示生成类了


具体化语法:
template <> class SortArray<const char char*>{…};
部分具体化:
通用:
template <class T1, class T2> class Pair{…};//通用类模板
template class Pair<T1,int> {…};//部分具体化,后面参数int;
具体化: template<> class Pair<int,int> {…};

成员模板:类模板之中还有template,而且参数还与模板类不一样;(但最终,还是得通过各

种方式得到一个类型);
将模板用作参数:
template <template class Thing>
class Crab { 这个要在类中指定Thing的T; 比如:Crab 就要在其中指定Stack

中的T;
这只有一个参数,还有多个参数: template<template class Thing,

typename U, typename V> class Crab
Crab<Stack,int,double> nebulas;
友元带模板的:
template
class HasFriend{
friend void report(HasFriend &);
};
模板别名:typedef std::array<double,12> arrd; //1.
template using arrtype = std::array<T,12>; //2
c++11允许将语法using=用于模板,用于非模板时,与常规typedef等价;

dynamic_cast<Type *>(pt);

如果可能的话,dynamic_cast运算符将使用一个指向基类的指针来生成一个指向派生类的指

针;否则,该运算符返回0,空指针;
typeid运算符返回一个指出对象的类型的值;
type_info结构存储了有关特定类型的信息;
只能将RTTI用于包含虚函数的类层次结构,原因在于只有对于这种类层次结构,才应该

将派生对象的地址赋值给基类指针;
Super* pm = dynamic_cast<Super >(pg); //指针pg的类型是否可被安全地转换为Super,

如果运行符将返回对象的地址;否则返回一个空指针;

if(ps = dynamic_cast<Superb*>(pg) ps->Say(); //如果转换成功,则调用派生类方法;
typeid(Magnificent == typeid(*pg) //如果相等;

const High *pbar = &bar;
High pb = const_cast<High>(pbar);

reinterpret_cast用于天生危险的类型转换;适用于底层编程,不可移植;
unique_ptr pi{ new int };

for_each(books.begin(),books.end(),ShowReview);
seekg(0, ios::end) 不是end of file 而end of file的时候, seek是无效的, 必须先

clear.

STL是一种泛型编程,泛型编程关注的是算法,创建可重用的代码,旨在编写独立于数据类型

的代码;
STL自带容器的算法,应该尽可能用通用的术语来表达算法,使之独立于数据类型和容器类型

,为使用通用算法能够适用于具体情况,应定义能够满足算法需要的迭代器,并把要求加到

容器的设计上,即基于算法的要求,设计基本迭代器的特征和容器特征;
STL定义了五类迭代器:输入输出,正向双向,最后加随机访问迭代器;
输出是只写,正向重载++,向前移动,保存后仍可以获值;正向迭代器能读能写,也可只读


双向:同时支持++,--;
deque,list,queue,priority_queue,stack,vector,map,multimap,set,multiset,bitset;

C++11:

forward_list,unordered_map,unordered_multimap,unordered_set,unordered_multiset;
a.erase(q,p);
a.clear() 等价于erase(begin(),end())
几种容器比较:

  1. vector在尾部操作 时间固定;
  2. deque双端队列: 多数操作发生在首尾,则时间固定;
  3. list强调元素的插入和删除操作,写操作强;
  4. forward_list:单链表;每个节点只链接到下一个节点,只需要正向迭代器,不可反转的

容器;
5.queue: 把使用限制在定义队列的基本操作上,可以将元素添加到队尾,从队首删元素;
6.priority_queue: 优先权队列,最大元素在队首; priority_queue pq2

(greater);
关联容器: x::value_type,x::key_type; 关键容器提供对元素的快速访问;无法指定元素

的插入位置;关联容器通常有用于确定数据放置位置的算法,以便能快速检索信息;

无序关联则是哈希表,旨在提高添加和删除元素的速度以及提高查找算法的效率;

函数对象,也叫函数符(functor)
生成器,是不用参数就可以调用的函数符;

bool tooBig(int n){ reutrn n >100;}
list scores;
scores.remove_if(tooBig);
然后结合模板就可以实现类似于这样的灵活的函数符: TooBig(200) //大于200的整

型数;//用template生成模板类型T,然后类重载()后就可以传参,实例化int后传参200;
transform(gr8.begin(),gr8.end(),out,sqrt); //计算方根后发给out;

当函数的参数个数不统一时,STL提供了适配器bind,binder1st,binder2nd;
bind1st和bind2nd函数用于将一个二元算子转换成一元算子。如:vec.erase(remove_if

(vec.begin(),vec.end(),bind2nd(greater(),100)),vec.end());
c++11提供了函数指针和函数符的替代器:lambda表达式;
STL将算法分为4组:
1.非修改式序列操作
2.修改式序列操作
3.排序和相关操作
前三个在algorithm头文件中
4.通用数字运算; 这个在numeric中

begin(),end()有非成员的版本;
initializer_list();
std::cout << hex; //16进制显示;
dec(cout) 还原10进制;
std::cout.precision(4); //指有效数字,如果10.11,就是10.11,如果是.141596就是

0.1415;
cin,cout对象包含一个流状态的数据成员,流状态由3个ios_base元素组成,

eofbit,badbit,failbit;goodbit;
函数:good(),eof(),bad(),fail(),rdstate(),exceptions();

if( !fin.is_open()); //检测文件是否成功打开;新标准的检测方式;老版本没有这个函数


文件模式:ios_base::in,ios_base::out,ios_base::ate,::app,::trunc,::binary;
is_base::trunc打开己有文件,以前的内容将被删除;
ofstream fout(“basels”,ios_base::out | ios_base::app); // C的"a" ; 打开追加
以二进制读写时,不会发生转换,而且检测文件尾的方式也有区别;
写文件: ofstream fout (“pl.dat”, ios_base::out | ios_base::app |

ios_base::binary);
fout.write((char*) &pl,sizeof pl);
一般用来检测是否到文件未:while (std::cin.get() != ‘\n’) continue;
移动文件中的指针: seekg()输入指针移动指定位置,seekp()用于oftream对象;
位置seek_dir:ios_base::beg;ios_base::cur,ios_base::end;
fin.seekg(-1,ios_base::cur);
fin.seekg(112); //将文件指针指向112个字节;
检测位置:分输入输出;对于输入流,tellg(),对于输出流:tellp() 都返回streampos值

;字节为单位,文件开始算;
-----------
#include

ostringstream outstr;
outstr << “the hard disk” << hdisk << “has a capcity;”;
string result = outstr.str() //上面的把输入字符串格式化;存入outstr;
不仅有输出,还有变量输入,然后合成字符串;
sstream头文件定义了istringstream,ostringstream类,这些类使得能够使用

istream,ostream方法来抽取字符串的信息,并对要放入到字符串中的信息进行格式化;
C++11: 
新增long long, unsigned long long 新增类型char16_t,char32_t;
decltype(&x) pd; //pd same as &x;
别名:using itType = std::vectorstd::string::iterator;
显示转换运算符: class Plebe { explicit Plebe(double);
扩展了转换: explicit operator double() const;
移动赋值:Useless& Useless::operator=(Useless && f){…
默认编译器是增加移动复制和移动赋值构造函数的;
默认方法和禁用方法:函数后面 =default; = delete;
以前禁用复制构造函数是声明为私有,现在只需要声明 = delete; 就禁用了;
default只能用于6个特殊成员,但delete可以用于任何成员函数;
C++11标准引入了一个新特性:defaulted函数。程序员只需在函数声明后加上”=default;”

,就可将该函数声明为defaulted函数,编译器将为显式声明的defaulted函数自动生成函数

体。C++11允许我们使用=default来要求编译器生成一个默认构造函数:
c++11允许您在一个构造函数的定义中使用另一个构造函数,这被称为委托;
Notes::Notes():Notes(0,0.0,“Oh”){//} //在构造函数中调用Notes(***)
C++11: 继承构造函数 using C1::fn;
C++11将这种方法用于构造函数,这让派生类继承基类的所有构造函数(默认构造函数,复制

构造函数和移动构造函数除外),但不会使用与派生类构造函数特征标匹配的构造函数;
C11对虚方法的管理: override,final;
对于重载:加override;对于私有或是封闭类,加final;
virtual void f(char* cha) const override{ std…} 注意位置
virtual void f(char ch) const final{…} 注意位置;
Lambda表达式{} // 捕获,参数,函数体
在c++中引入lambda的主要目的是,让您能够将类似于函数的表达式用作接受函数指针或函数

符的函数的参数。
c++11包装器(适配器)包括:bind,meme_fn,reference_wrapper,function;
mem_fn能够把成员函数当常规函数传递;模板reference_wrapper让您能够创建行为像引用,

但可被复制的对象,function让您能够以统一的方式处理多种类似于函数的形式;
#include function<double(double)> ef1 = dub; //返回值,参数
这种方式即可以接受函数,函数对象,labmda表达式;
auto fn_half = std::bind(funname,_1,2); //第一个是函数名,第二个是占位符;
auto f = std::bind(&Foo::print_sum, &foo, 95, std::placeholders::_1);
bind(print, ref(os1), _1, c) //绑定引用参数;
可变参数模板:
template <typename… Args>
void show_list(Args… args){…}
添加thread_local,将变量声明为静态存储,其持续性与特定线程相关,即定义这种变量的线

程过期时,变量也将过期;库支持:atomic,原子操作库;线程运行库:

thread,mutex,condition_variable,future;
C++11专用库:random:分布状态,均匀分布,二项式分布,正态分布;
chrono提供处理时间间隔;tuple,pair;分数ratio;正则regex;
要获取类型或对象的对齐要求,使用alignof(),要控制对齐方式,使用alignas;
constexpr在编译阶段计算结果为常量的表达式,让const变量可存储在只读内存中;
static_assert可以用于在编译阶段进行断言;主要针对编译阶段实例化的模板;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值