重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
转载自https://github.com/applenob/Cpp_Primer_Practice,看C++primer的时用的笔记。自己做了一些补充,感谢前人的总结!
这章比较难,初学C++的可以结合《Essential C++》的第五章学习。回过头来再看这一章会轻松一点。
成都创新互联是一家专注于网站建设、成都网站建设与策划设计,百色网站建设哪家好?成都创新互联做网站,专注于网站建设十多年,网设计领域的专业建站公司;建站业务涵盖:百色等地区。百色做网站价格咨询:18980820575
拷贝控制操作(copy control):
class Foo{ public: Foo(const Foo&); }
string book = "9-99";
=
定义变量时。operator=
的函数.Foo& operator=(const Foo&);
static
成员赋予左侧运算对象的对应成员。static
数据成员。~Foo();
delete
运算符时。=default
来显式地要求编译器生成合成的版本。=delete
。private
声明来阻止拷贝。类的行为可以像一个值,也可以像一个指针。
行为像值:对象有自己的状态,副本和原对象是完全独立的。
行为像指针:共享状态,拷贝一个这种类的对象时,副本和原对象使用相同的底层数据。
//赋值运算符组合了析构函数和拷贝构造函数的工作,先在底层生成对象空间,删除类内原有的内存空间,然后指向新分配的指针。
HasPtr& operator=(const HasPtr& hp){
auto new_p=new std::string (*hp.ps);//拷贝底层string
delete ps;//释放旧内存
ps=new_p;//从右侧运算对象拷贝数据到本对象
i=hp.i;
return *this;//返回本对象
}
swap
的函数。swap
而不是std::swap
。string
和shared_ptr
类既可以支持移动也支持拷贝。IO
类和unique_ptr
类可以移动但不能拷贝。&&
获得右值引用。move函数:
int &&rr2 = std::move(rr1);
move
告诉编译器,我们有一个左值,但我希望像右值一样处理它。move
意味着:除了对rr1
赋值或者销毁它外,我们将不再使用它。StrVec::StrVec(StrVec &&s) noexcept{}
StrVec& StrVec::operator=(StrVec && rhs) noexcept{}
合成的移动操作:
只有当一个类没有定义任何自己版本的拷贝控制成员,且类的每个非static数据成员都可以移动时,编译器才会为它合成移动构造函数或移动赋值运算符。如string
中有移动操作,就可以生成合成的移动操作。
如果显示的要求编译器生成=default的移动操作,且编译器不能移动所有成员时,编译器会将移动操作定义为删除的函数。
一个类是否定义了自己的移动操作对拷贝操作如何合成有影响。如果类定义了一个移动构造函数和/或一个移动赋值运算符,则该类的合成拷贝构造函数和拷贝赋值运算符会被定义为删除的。
make_move_iterator
函数讲一个普通迭代器转换为一个移动迭代器。const T&
,而另一个版本接受一个T&&
。&
,限定只能向可修改的左值赋值而不能向右值赋值。Foo& operator=(const Foo&) &;//防止对右值赋值
引用限定符可以是&和&&,对于&限定的函数,我们只能将它用于左值;对于&&限定的函数,只能用于右值:
Foo &retFoo();//返回一个引用;retFoo调用是一个左值
Foo retVal();//返回一个值,retval调用是一个右值
Foo j;
retFoo()=j; //正确,retfoo返回一个左值
retVal()=j; //错误,retval()返回一个右值
j=retval(); //正确,我们可以将一个右值作为赋值操作的右侧运算对象
一个函数可以同时用const和引用限定,引用限定符&必须跟随在const限定符后。
当定义const成员函数时,可以定义两个版本,唯一的差别是一个版本有const限定而另一个没有。引用限定的函数不同。如果定义两个或两个以上相同名字和相同参数列表的成员函数,就必须对所有函数都加上引用限定符,或者都不加。