《Cpp-Primer-Plus》-第十一章 实用类

第十一章 使用类

记录CCPlus十一章内容,包含许多c++特性

博文地址

知识整理

运算符重载

运算符重载允许赋予c++运算符多种含义,c++根据操作数的数目和类型来决定采用哪种操作。

要重载运算符, 需使用运算符函数的特殊函数形式

operator op(argument list);

在运算符表示法中,运算符左侧的对象是调用对象,运算符右侧的对象是作为参数被传递的对象

c++对运算符重载的限制

  1. 重载后的运算符必须至少有一个操作数是用户定义的类型

  2. 使用运算符时不能违反运算符原来的句法规则

  3. 不能修改运算符的优先级

  4. 不能创建新运算符

  5. 不能重载以下运算符

    sizeof.::?:typeid,const_castdynamic_castreinterpret_caststatic_cast

友元

c++公有类方法可以访问类对象私有部分,但有些情况会有许多限制。

举书上的例子,*重载运算符函数使用如下

A = B * 2.75; // A,B都为类对象
A = B.operator+(2.75);  //转换为成员函数调用

但乘法还可以A = 2.75 * B,此时的重载成员函数就不能用于这种情况, 这时候就需要非成员函数,又非成员函数不能访问私有部分,于是友元函数就出来了。

通过让函数称为类的友元,可以赋予该函数与类的成员函数相同的访问权限。

要创建友元函数,先将函数原型放在类声明中,并在原型前加上关键字friend

friend ClassName operator*(double m, const ClassName & t) const;

虽然函数是在类声明中声明的,但其不是成员函数,所以函数定义时不要使用::,也不要在定义中使用关键字friend

ClassName operator*(double m, const ClassName & t) {
    
}

有了上述友元函数后,就可以使用A = 2.75 * B;语句了。

书上还有一个常用友元的例子,重载<<运算符

假设trip是一个类对象,要实现cout << trip;

如果使用一个成员函数来重载<<,就像使用成员函数重载*运算符那样,就必须trip << cout;才能有效,但这样显然是不好的,这时可以使用友元函数重载

void operator<<(ostream &os, const ClassName & t){

}

这样就可以使用cout << trip;,但这样不能和其他混合打印,如cout << "Trip: "<<trip<<" \n";

这里需要注意,ostream类将operator<<()函数实现为返回一个指向ostream对象的引用,所以可以连续使用。

可以对友元函数采用同样的方法

ostream & operator<<(ostream & os, const ClassName & t){
	os<<....
    return os;
}

因为返回类型是ostream&,所以可以连续使用。

那么,重载运算符是作为成员函数还是非成员函数呢?

对于某些运算符来说,成员函数是唯一合法的选择,但一般情况下,使用友元函数比较好。

类的自动转换和强制类型转换

c++存在内置类型转换,将一个标准型变量的值赋给另一种标准类型的变量时,若这两种类型兼容,则c++自动将这个值转换为接收变量的类型。

c++也可以将类定义与基本类型或另一个类相关,使得从一种类型转换为另一个类型有意义,如书上的例子

ClassName(double lbs); // 构造函数

ClassName cn;
cn = 19.6;  // 自动转换使用构造函数

只有接受一个参数的构造函数才能作为转换函数,有两个参数不能转换,除非第二个参数有默认值。

同时,为了防止意外的类型转换,c++新增了关键字explicit,用于关闭隐式转换,只能显式转换。

explicit ClassName(double lbs);

ClassName cn;
cn = 19.6;  // 不允许隐式转换
cn = ClassName(19.6);
cn = (ClassName)19.6  // 允许显式转换

c++还可以将类对象转换为内置类型,但必须使用转换函数

ClassName cn(34.6);
double host = double (cn); //有转换函数成立
double thin = (double) cn; // 有转换函数成立

转换函数要怎么创建呢?

operator typename();

同时需要注意以下几点

  1. 转换函数必须是类方法
  2. 转换函数不能指定返回类型
  3. 转换函数不能有参数
operator double();

ClassName::operator double(){
	
	return (double)..;
}

和转换构造函数一样,转换函数也会发生意想不到的转换,所以也可以使用关键字exlicit关闭隐式转换。

转换最好使用显式转换。

复习题

  1. 友元函数与成员函数之间的区别是什么?

    成员函数是类定义的一部分,通过特定的对象来调用。友元函数不是类的组成部分,可以直接调用。

  2. 非成员函数必须是友元函数才能访问类成员吗?

    要访问私有成员,必须是友元函数

  3. 哪些运算符不能重载?

    sizeof..*::?:

  4. 在重载运算符=()[]->时,有什么限制?

    以上运算符必须使用成员函数定义,不能使用友元函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值