C++Primer 第十四章

//1.当运算符作用于类类型运算对象时,可以通过运算符重载重新定义该运算符的含义。明智的使用运算符重载能令程序更加易于编写和阅读。

//2.重载的运算符是具有特殊名字的函数,它们由关键字operator和其后要定义的运算符号共同组成。和其它函数一样,重载的运算符也包含返回类型,参数列表以及函数体。

//3.除了重载函数调用符之外,其余的重载运算符不能含有默认实参。

//4.如果运算符函数是成员函数,则其左侧运算对象绑定到隐式的this指针。
//  对于运算符函数来说,它或者是类的成员,或者至少含有一个类类型的参数。即无法改变运算符作用于内置对象时候的操作。

//5.对于重载的运算符来说,其优先级和结合律是无法被改变的。

//6.某些运算符指定了运算对象的求值顺序。因为使用重载的运算符本事是一次函数调用,所以这些运算对象求值顺序的规则无法应用到重载的运算符上。
//  && || , 的求职顺序规则无法保留下来。 && || 的短路求值属性也无法保留,因此一般不对这些运算符进行重载。
//  C++语言已经定义了, 和 & 用于类类型对象时候的特殊含义,这一点与大多数运算符都不相同,所以一般也不要进行重载。

//7.当重载了==运算符的时候,一般也需要重载!=。重载了<则一般也要重载>。若重载了算数运算符或者位运算符,则最好也提供其复合版本。

//8.当我们定义重载的运算符的时候,必须首先决定是将其声明为类的成员函数还是类的非成员函数。其区别是:类的成员函数版本的重载运算符其左侧操作对象必须是该类的对象。
//  一般来说 = () [] -> 必须定义为类的成员函数版本。
//  重载的复合运算符一般来说作为类的成员函数,但非必须。
//  改变对象状态的运算符或与给定类型密切相关的运算符,比如 递减, 递增, 解引用 通常为作为类的成员函数。
//  具有对称性的运算符可能转换任意一端的运算对象,例如 算数 相等性 关系 位运算符等,通常应该是类的非成员函数(需按照类类型对象的位置,定义多个版本的重载运算符函数)。
//  尽量使重载的运算符与其内置的版本表现一致。

//9.如果存在唯一一种可靠的<定义,则应该考虑为这个类定义<运算符(关联容器和一些算法需要此运算符)。如果类同时还包含==,则当且仅当<定义和==结果是一致的时候才定义<(这里的结果一致的意思是:当不能满足==的时候,2个对象必须有一个是<另一个的)。

//10.下标运算符的内置版本是返回引用类型,所以其重载类型最好也返回引用类型,而且通常定义下标运算符的常量版本和非常量版本,防止作用于一个常量对象时不会给其返回的对象赋值。

//11.为了与内置版本保持一致,重载前置的递增递减运算符应该返回引用类型。后置的递增递减运算符应该按值返回。后置的递增递减运算符额外接受一个不被使用的int类型的实参(将会被置为0)来区别其前置版本。

//12.很多具有互相作用的运算符的重载,其工作可以交予其具有相关联关系的运算符重载函数完成,比如==的工作可以交予!=来完成等。

//13.箭头运算符永远不能丢掉其成员访问的这个基本含义。可以改变的是箭头从哪个对象当中获取成员,而箭头获取成员这一个事实则永远不变。所以:重载的箭头运算符必须返回类的指针或者自定义了箭头运算符的类的某个对象。
//   point->men;根据point的类型不同分别等价于:
//   A:(*point).men;            point是一个内置的指针类型
//   B:point.operator()->men;    point是类的一个对象。
class CTest
{
public:
    CTest()                    {str = "szn";}
    string* operator ->()    {return &str;}
public:
    string str;
};
CTest Test;
const char *pStr0 = Test->c_str();            //pStr0 = "szn"
const char *pStr1 = (&Test)->str.c_str();    //pStr1 = "szn"

//14.函数调用运算符可以重载为多个版本,相互之间在参数数量或者类型上有所区别。由于类的对象能存储状态,所以比起普通函数来说更加灵活。

//15.function位于头文件functional中,声明在命名空间std中,用于存储一个可调用对象。注意:重载的函数名字不能直接存入function类型的对象中,可以使用函数指针或lambda等来解决这个问题。
int Add(int value0, int value1)    {return value0 + value1;}
int Minus(int i, int j)            {return i - j;}

class CMultiply
{
public:
    CMultiply(){}
    int operator()(int value0, int value1){return value0 * value1;}
};

CMultiply multiply;
auto divide = [](int i, int j){return j == 0 ? 0 : i / j;};
auto minus = bind(Minus, _2, _1);

map<string, function<int (int , int)>> mapFun;
mapFun.insert(make_pair(string("+"), Add));
mapFun.insert(make_pair(string("-"), minus));
mapFun.insert(make_pair(string("*"), multiply));
mapFun.insert(make_pair(string("/"), divide));

int v0 = mapFun["+"](10, 5);    //v0 = 15
int v1 = mapFun["-"](10, 5);        //v1 = -5
int v2 = mapFun["*"](10, 5);    //v2 = 50
int v3 = mapFun["/"](10, 5);    //v3 = 2

//16.通过定义转换构造函数可以将指定类型的对象转换为类类型的对象。通过定义类型转换运算符可以将类类型的对象转换为指定类型的对象。转换构造函数和类型转换运算符共同组成了类类型转换。
//   在实际操作中,很少提供类的类型转换运算符,在大多数情况下,如果类型转换自动发生,用户可能感觉比较意外,而不是感觉受到了帮助。特殊的:对于类来说,定义向bool的类型转换还是比较普遍的。
class CTest
{
public:
    CTest() : value(0){}
    operator int() const {return value;}    //不能声明返回类型,形参列表必须为空,通常是const的。
private:
    int value;
};

CTest Test;
int value = Test;    //value = 0

//17.
时间: 2024-12-26 04:14:03

C++Primer 第十四章的相关文章

C++primer第十四章 重载操作符与转换

这些标准库的类型具有相同的操作符,使用它们就像使用内置数组和指针一样.允许程序使用表达式而不是命名函数,可以使编写和阅读程序容易得多.将 cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << endl; 和以下更为冗长的代码相比较就能够看到.如果 IO 使用命名函数,类似下面的代码

javascript高级程序设计 第十四章--表单脚本

javascript高级程序设计 第十四章--表单脚本 在HTML中表单由<form>元素表示,在js中表单对应的是HTMLFormElement类型,这个类型也有很多属性和方法:取得表单元素的引用还是为它添加id特性,用DOM操作来获取表单元素:提交表单:把<input>或<button>元素的type特性设置为"submit",图像按钮把<input>元素的type特性设置为"image",也可以调用submit(

java-第十四章-代参的方法(二)-实现MyShopping系统的添加会员功能

 package com.wxws.sms; public class Customer {  int No;  int integarl; } package com.wxws.sms; public class Customers {  Customer[] customers = new Customer[100];  public void add(Customer cust){   for (int i = 0; i <customers.length; i++) {    if (c

java-第十四章-代参的方法(二)-查找会员积分

 package com.wxws.smsB; public class Customer {  int No;  int integarl; } package com.wxws.smsB; public class Customers {  Customer[] customers = new Customer[100];  public void add(Customer cust) {   for (int i = 0; i < customers.length; i++) {    i

C Primer Plus (第四章总结)

1.定义字符串可以直接在头文件下定义,如: #include <stdio.h> #define hello  "hello world!" 2.sizeof() 和 strlen() sizeof运算符是以字节为单位给出数据的大小,strlen()是以字符为单位给出长度. <string.h>包含许多与字符串相关的函数的原型,包括strlen() sizeof运算符提供的数据比肉眼直观的要大多一位,因为他把用来标志字符串的不可见的空字符也计算在内. 定义常量最

R in action读书笔记(19)第十四章 主成分和因子分析

第十四章:主成分和因子分析 本章内容 主成分分析 探索性因子分析 其他潜变量模型 主成分分析(PCA)是一种数据降维技巧,它能将大量相关变量转化为一组很少的不相关变量,这些无关变量称为主成分.探索性因子分析(EFA)是一系列用来发现一组变量的潜在结构的方法.它通过寻找一组更小的.潜在的或隐藏的结构来解释已观测到的.显式的变量间的关系. PCA与EFA模型间的区别 主成分(PC1和PC2)是观测变量(X1到X5)的线性组合.形成线性组合的权重都是通过最大化各主成分所解释的方差来获得,同时还要保证个

c++第十四章-(类型强转换)

类型强转换有2种. class Company { public: Company(std::string theName,std::string theProduct); virtual void printInfo(); protected: std::string name; std::string product; }; Company::Company(std::string theName,std::string theProduct) { this->name = theName;

Java-第十四章-代参的方法(二)-编程实现,输入班里10名学生的身高,获得身高最高的学生要求对象数组类型方法

package com.ww.yzpA; public class Students { int No; int Height; } package com.ww.yzpA; public class Height { public Students getMaxHeigth(Students[] str) { Students A = new Students(); for (int i = 0; i < str.length; i++) { if (str[i].Height > A.He

CSS3秘笈复习:十三章&amp;十四章&amp;十五章&amp;十六章&amp;十七章

第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮动元素.关键字:left.right或both. (2).浮动外围元素:让包含浮动元素的<div>也浮动.选择这种方法一定要在浮动容器后面的任何元素中添加一个clear属性,确保浮动元素落到容器的下方. (3).利用overflow : hidden.另一种常见的方法是在外围的样式中添加以下属性: