友元:友元函数,友元类,友元成员函数。
友元函数:在类当中使用friend声明的函数。但是在定义的时候不可以加friend关键字。
友元函数拥有成员函数调用私有成员的权限,但是不属于类(不会在类创建的对象中)。
运算符重载:可以使用成员函数重载也可以使用非成员函数(友元函数重载,也可以不是友元函数)重载。
运算符重载的要求:
- 必须有一个是用户自定义类型
- 不可以修改运算符的操作数个数和优先级
- 不能自己创造运算符
- 必须在成员函数当中重载的运算符[],(),->,=
- 不能重载的运算符 sizeof(),.成员运算符,.*成员指针运算符,?:条件运算符,::作用域解析运算符,4种强制转换运算符:dynamic_case,static_cast,reinterpret_cast,const_cast.
成员函数重载运算符:
class Sale
{
Sale operator+(Sale &s);
};
// 使用重载运算符
Sale a,b,c;
c = a.operator+(b);
c = a + b;
成员函数重载默认会带一个参数就是调用成员函数的对象。
友元函数重载运算符:
一般的应用:1.使成员运算符函数符合加法结合律。
// 交换律实现
class Sale
{
Sale operator+(double num);
};
// 使用方法
Sale a,b;
double num;
b = a + num; // 此处不能交换,因为+其实际使用是b = a.operator+(num); 所以a是一个调用对象,而double没有该方法可以调用
// 在类中加入
friend Sale operator+(double num, Sale &a);
// 定义
Sale operator+(double num, Sale &a)
{
return a + num;
}
b = num + a; // 此时调用友元函数定义的运算符函数
2.用在<<重载上,通常结构的固定的
// 对对象使用cout << 进行输出
class Sale
{
friend ostream & operator<<(ostream & os, Sale &s);
};
// 这种定义方法可以实现. cout << a << b;连续输出
非友元函数的非成员函数实现
当对象对齐要输出的值,有类方法实现,那此时定义一个使用cout << 进行输出的运算符函数,就不需要访问对象的内部数据,所以直接使用非友元函数。
类型转换
类型转换可以多次进行:如将int转换成double再转换成对象
类型转换不希望使用隐式转换,可以使用explicit禁用饮食转换。
隐式转换的情况:
- 函数传参数和返回参数
- 类型的初始化和赋值
c++提供了:基本类型到用户定义类型的转换,用户定义类型到基本类型的转化。每一种转换都包括显示转换和隐式转换。
基本类型到用户定义类型的转换:使用使用一个参数调用的构造函数作为转换函数。
class Sale
{
Sale(int a);
Sale(double a,int b = 1);
// 两个都可以作为转换函数
};
// 隐式调用方法
Sale a = 1;
// 显示调用方法
Sale a = Sale(1);
Sale a = (Sale)1;
用户定义类型到基本类型的转化:单独定义的转换函数,必须是成员函数。
class Sale
{
operator double();
};
Sale::operator double()
{
return a; // 必须有返回值,但是函数原型不含返回类型和参数
}
Sale a ;
// 隐式使用
double b = a;
// 显示使用
double b = double(a);
过多的类型转换可能导致二义性:
// 类中定一个两个方向的转换
Sale a,b;
double c;
a = b + c;
// 两种解释,将c转化成Sale对象,然后加法。
// 将b转化成double,然后加法
代码:
cstdlib中包含rand和srand操作。
cmath包含sqrt,cos,sin,atan,atan2。
ctime包含时间
代码技巧:
对于小时和分这种转化,可以统一成分,然后进行加减,之后在转化成小时和分的组合形式。
使用状态成员:对于类中有不同的表示数据的方法,则可使用状态成员进行区分。
对于创建对象时:尽量使用构造函数创建,而不是赋值。
Vector矢量的例子当中得出:
1.编译指令:using声明和using 编译放在名称空间之外,防止重复定义,出现二义性。
2.默认参数:只在原型当中使用
3.友元函数访问类中的私有变量:1.通过对象。2.利用类作用域。
4.对于能使用括号的地方尽量使用括号,防止优先级出现问题。
5.c++中,平方使用x*x没有x^2
6.构造函数定义当中的初始化,不能嵌套。