P321 string
string的一种初始化方式:
const char*p=“abc”;
string s§;//s==“abc”,拷贝p指向的字符串直到遇到空字符
char p1[]={‘a’,‘b’,‘c’};
string s1(p1);//s1!=“abc”
P356 bind P417 P424 智能指针管理动态分配的数组: P476 P480 函数的异常说明符noexcept,常量成员函数const,左/右值引用成员函数(用于说明this指向一个左值/右值),这些函数的这些说明符必须同时出现在声明和定义中。这三个指示符可以同时出现。
函数适配器,#include
可以使用占位符
void f1(int a,int b)
{}
auto p=bind(f1,std::placeholders::_2,std::placeholders::_1);
p(1,2)//==f1(2,1)
如果是不能拷贝的对象,比如ostream,可以使用ref函数,此函数返回一个对象,包含给定的实参的引用。
int a=1;
auto p=ref(a);//p可以隐式转为int
p.get()=2;
cout<
unique_ptr不支持普通的拷贝或赋值操作,但是可以拷贝或赋值一个将要被销毁的unique_ptr.在此情况下,编译器执行移动构造或者移动赋值。
动态分配一个空数组是合法的,
int*p=new int[0];//p!=nullptr,p是一个合法的非空值。此指针保证与new返回的其它任何指针都不同。但是解引用得到的是一个未定义值。也就是说解引用没有任何意义。
shared_ptr:
shared_ptr
for(size_t i=0;i<2;++i)
{
*(p.get()+i)=i;
}
unique_ptr:
unique_ptr
for(size_t i=0;i<2;++i) p1[i]=i;
如果一个类有自己的拷贝构造函数,没有定义移动构造函数,则编译器不会合成默认的移动构造函数;同理,如果一个类有自己的移动构造函数,则其合成的默认拷贝构造函数是delete;
P 478
如果类有移动构造函数和拷贝构造函数,则拷贝并交换赋值运算符既是移动赋值运算符,也是拷贝赋值运算符。class c1
{
public:
c1(const c1&)//拷贝构造函数
{
cout << "const c1&" << endl;
}
c1(c1&&)noexcept//移动构造函数
{
cout << "c1&&" << endl;
}
c1& operator=(c1 temp)//即是拷贝赋值,也是移动赋值
{
return *this;
}
c1() = default;
};
c1 a, b;
a = b;//拷贝赋值
a = std::move(b);//移动赋值
移动迭代器:
解引用得到一个右值引用。通过make_move_iterator(迭代器)得到一个移动迭代器;
使用std::move 或移动迭代器应该确保使用后不再访问对应的原来的对象。使用后原来的对象状态是正确的,可以析构的,但是对象中的值是不确定的。#include
class c1
{
public:
void f1() const & noexcept //三个说明符必须以这样的顺序书写:const &/&& noexcept
{
cout << this->a;
}
};



