第13章 拷贝控制

使用default:=defult只能修饰默认构造函数或拷贝控制成员,显式地要去编译器生成合成的版本。

使用delete:=delete通知编译器不希望定义这些成员,禁止试图使用它的操作,通常的用途是禁止拷贝控制成员,或引导函数匹配。

析构函数不能是delete的,如果删除了析构函数,我们只能动态分配这种类型,并且不能释放这些对象。(非动态类型会被系统自动释放)

定义行为像值的类:如果将一个对象赋予它自己,赋值运算符必须能正确工作(对象内含指针的时候);大多数赋值运算符组合了析构函数和拷贝函数的工作。

class P{
public:
//各个函数
private:
std::string &ps;
int i;
};
P& P::operator = (const P &rhs){
auto newp = new string(*rhs.ps);
delete ps;
ps = newp;
i = rhs.i;
return *this;
}

定义行为像引用的类:指针指向同一块内存

class P{
public:
//各个函数
private:
std::string &ps;//拷贝、赋值时,ps指向同一块内存
int i;
std::size_t *use;//*use表示引用计数,*use = 0时释放内存
};

 定义swap:

定义swap的意义在于类中存在指针的话,指针指向的内存可能会再次得到分配(如果定义的是行为像值的类),而实际上交换指针效率更高。

class P{
friend void swap(P& , P&);
//其他成员定义
};
inline void swap(P &lhs, P &rhs){
using std::swap;
swap(lhs.ps, rhs.ps);//使用自己定义的swap交换指针类型, 匹配程度优于std::swap
//交换其他成员
}
//下述代码与默认的swap效率无异,应当使用自己定义的swap
//inline void swap(P &lhs, P &rhs){
// std::swap(lhs.ps, rhs.ps);//使用了标准库的swap
//}

通过swap重载 =

//rhs是按值传递的, 自动处理了自赋值情况且天然就是异常安全的
P& P::operator = (P rhs){
swap(*this, rhs);
return *this;
}

对象移动:

右值引用:必须绑定到右值的引用。右值引用只能绑定到一个将要销毁的对象。

通过右值引用,可以完成移动构造函数和移动赋值运算符。

std::move()获得绑定到左值上的右值引用。

只有当类没有定义自己版本的拷贝控制成员且类的每个非static数据成员都可以移动,编译器才会为它合成移动构造函数或移动赋值运算符。

定义了一个移动构造函数或移动赋值运算符的类必须也定义自己的拷贝操作,否则这些成员默认被定义为删除的。

一些标准库,包括string都定义了移动构造函数。

如果类既有移动构造函数又有拷贝构造函数,则通过函数匹配规则来确定使用哪个构造函数,赋值操作类似;如果没有移动构造函数,右值也被拷贝。

个人感觉,移动构造函数类似于通过把右值的指针赋值过去,并修改右值的指针为空来提高效率。

重载和引用函数:类似于const函数,在参数列表后放置一个引用限定符(&或&&)指出this的左值/右值属性的方式。如果一个成员函数有引用限定符,则具有相同参数列表的所有版本都必须有引用限定符。

第14章 重载运算与类型转换

把二元运算重载为成员函数时,运算的 LHS 是 *this。如果 LHS 为基本类型或是不可修改源代码的类型,就需要重载为非成员函数(如IO类)。

重载为成员函数时,无参则重载的是一元运算符,有1个参数则重载的是二元运算符。

前置++: a.operator++();

后置++: a.operator++(0);

重载成员访问符:P &operator*(),   P *operator->(), 解引用通常是类的成员,返回引用;箭头运算符必须是类的成员,必须返回类的指针重载了箭头运算符的类的对象(即返回的值还能进行箭头运算)

函数调用运算符:定义了调用操作符的类,其对象称为函数对象,我们说这些对象的行为像函数一样。

struct absInt{
int operator()(int val) const {
return val < ? -val: val;
}
}; absInt absObj;
int x = absObj(-); // x = 10;

 函数对象常常作为泛型算法的实参。

sort接受第三个参数为二元谓词函数或函数指针,而priority_queue接受第三个参数为类型。

一般算法接受的是函数对象或函数指针,而容器适配器接受的是一个class类型。

如:

bool cmp(const int &a, const int &b){
return a < b ;
}
struct mycmp {
bool operator() (int i,int j) { return (i<j);}
};
int main(){
bool (*fun)(const int &, const int &) = cmp;
vector<int> ve;
//调用函数指针
sort(ve.begin(), ve.end(), fun);
sort(ve.begin(), ve.end(), cmp);
sort(ve.begin(), ve.end(), mycmp());
//lambda表达式
sort(ve.begin(), ve.end(), [](const int &lhs, const int &rhs){ return lhs < rhs;});
sort(ve.begin(), ve.end(), greater<int>() ); //ve存int, 按降排列, 第3个参数是greater<int>类型的一个未命名对象。
priority_queue<int, vector<int>, greater<int> > Q;
int a = greater<int>()(, ); // a = false, greater<int>是一个类, greater<int>()是一个对象/函数名, greater<int>()(3, 5)是调用函数
return ;
}

标准库定义的函数对象:less<Type>, greater<Type>, plus<Type>等

标准库function类型:function<T> f; 如function<int(int, int)> f1 = add;//声明了一个function类型,可以表示接受两个int,返回一个int的可调用对象。

类型转换运算符:operator type() const;是一种特殊成员函数,复制将类类型的值转换为其他类型。

//构造函数将int转换为类,类型转换符将类转换为int
class SmallInt{
public:
SmallInt(int i = ): val(i){
if(i < ||i > ) throw std::out_of_range("Bad SmallInt value");
};
operator int() const { return val;}
private:
std::size_t val;
}; SmallInt si;
si = ;
si = si+;

注意: int i = 42; cin << i; //cin会转换为bool类型。

为了防止上述情况发生,可用显式的类型转换符,用explicit修饰,如explicit operator int() const { return val;}

但在表达式中被用作条件时,编译器会自动进行显示的类型转换。

operator bool()一般被定义为explicit的。

避免有二义性的类型转换。

第15~16章 略

《C++ Primer》学习笔记【第三部分 类设计者的工具】的更多相关文章

  1. C++ Primer学习笔记(三) C++中函数是一种类型!!!

    C++中函数是一种类型!C++中函数是一种类型!C++中函数是一种类型! 函数名就是变量!函数名就是变量!函数名就是变量! (---20160618最新消息,函数名不是变量名...囧) (---201 ...

  2. C++Primer学习笔记《三》

    数组名事实上就是一个常指针,指向数组元素中第一个的地址,在程序中假设要用指针遍历数组,不能直接用数组名来自增或自减.由于它是常量,一般先把数组名保存一份同类型的指针,然后再用这个指针来自增或是自减来实 ...

  3. 深入理解Java虚拟机学习笔记(三)-----类文件结构/虚拟机类加载机制

    第6章 类文件结构 1. 无关性 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(即扩展名为 .class 的文件) 是构成平台无关性的基石. 字节码(即扩展名为 .class 的文 ...

  4. C++primer学习笔记(三)——Chapter 5

    5.1   Simple Statements 1.记得每个语句后面加上”;”不过现在编译器都有实时编译,一般都不会忘记的, 2.空语句 (1)就是啥都没有.只有一个“:” (2)还是有很多用处的,例 ...

  5. Scala学习笔记(三)类层级和特质

    无参方法 功能:将方法的定义转换为属性字段的定义: 作用范围:方法中没有参数,并且方法仅能通过读取所包含的对象属性去访问可变状态,而不改变可变状态,就可使用无参方法: 例子: abstract cla ...

  6. C++Primer第5版学习笔记(三)

    C++Primer第5版学习笔记(三) 第四/五章的重难点内容           你可以点击这里回顾第三章内容       因为第五章的内容比较少,因此和第四章的笔记内容合并.       第四章是 ...

  7. C#可扩展编程之MEF学习笔记(三):导出类的方法和属性

    前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的. 还是前面的代码,第二篇中已经提供 ...

  8. C++ Primer学习笔记(二)

    题外话:一工作起来就没有大段的时间学习了,如何充分利用碎片时间是个好问题. 接  C++ Primer学习笔记(一)   27.与 vector 类型相比,数组的显著缺陷在于:数组的长度是固定的,无法 ...

  9. PyQt4入门学习笔记(三)

    # PyQt4入门学习笔记(三) PyQt4内的布局 布局方式是我们控制我们的GUI页面内各个控件的排放位置的.我们可以通过两种基本方式来控制: 1.绝对位置 2.layout类 绝对位置 这种方式要 ...

随机推荐

  1. CSRF 攻击

    一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSR ...

  2. iOS 9的升级后的问题处理

    iOS 9变动影响SDK部分: 增加了bitCode编码格式,当SDK不支持bitCode时,用户集成时无法开启bitCode选项. 现象:用户集成SDK后无法编译通过,错误日志里包含了bitCode ...

  3. linux复制指定目录下的全部文件到另一个目录中

    linux复制指定目录下的全部文件到另一个目录中复制指定目录下的全部文件到另一个目录中文件及目录的复制是经常要用到的.linux下进行复制的命令为cp.假设复制源目录 为 dir1 ,目标目录为dir ...

  4. 【原创】(AMD)JavaScript模块化开发(dojo)

    AMD原理等在这里就不进行说明了,作者也是菜鸟一枚,只是对自己的一个实例进行说明,如有错误,望指出. 首先,先推荐一篇AMD方面的文章,有兴趣的可以参考:http://efe.baidu.com/bl ...

  5. [Java Web]Error parsing HTTP request header Note: further occurrences of HTTP header parsing errors

    手机客户端向服务器提交Http请求时,Tomcat抛出错误: 十二月 31, 2014 2:32:45 下午 org.apache.coyote.http11.AbstractHttp11Proces ...

  6. php截取中文字符串乱码问题

    一般情况下说到截取字符串我们都会想到substr 然而substr对英文字符串有不错的效果,但是中文可能就会报出各种各样的问题: 所以,我们要采用mb库里面的substr,也就是mb_substr() ...

  7. [已解决] C3p0连接配置

    #用户名 c3p0.user=test c3p0.user=root # 用户密码--> c3p0.password=test c3p0.password=root c3p0.driverCla ...

  8. JavaScript 动态脚本

    动态脚本,指的是在页面加载时不存在,但将来的某一个时刻通过修改DOM动态添加的脚本. <script type="text/javascript"> function ...

  9. 三分钟学会funsioncharts

    由于项目需求需要做一个报表,选择FusionCharts作为工具使用.由于以前没有接触过报表,网上也没有比较详细的fusionCharts教程,所以决定好好研究FusionCharts,同时做一个比较 ...

  10. 山东省第七届ACM省赛------The Binding of Isaac

    The Binding of Isaac Time Limit: 2000MS Memory limit: 65536K 题目描述 Ok, now I will introduce this game ...