第十一章 使用类

第十一章 使用类


本章的重点的深入讲类使用的一些难点,所有内容都是来自阅读《C++ primer》第六版的所作笔记。
重点如下:

  • 运算符重载
  • 友元函数
  • 重载 <<
  • 状态成员
  • 使用rand()
  • 类的自动转换和强制类型转换
  • 类转换函数

在这里插入图片描述

1.运算符重载

重载运算符需要使用运算符函数的特殊形式,运算符函数的格式是:operatorop(argument-list)

例如现在,district2, sid, sara都是Salesperson类对象有 district2 = sid + sara;
编译器发现,操作数是Salesperson的类对象,使用相应的运算符函数来替换上述运算符:
distric2 = sid.operator(sara).

2.运算符重载的限制

  • 重载后的运算符必须至少有一个数是操作数是用户的定义的类型,这将防止用户为标准类型定义重载运算符
  • 使用运算符时不能违反运算符原来的句法规则(例如不能修改优先级)
  • 不能创建新的运算符
  • 不能重载下面的运算符
    • sizeof
    • .:
    • .*
    • ::
    • ?;
    • typeid
    • const_cast
    • dynamic_cast
    • reinterpret_cast
    • static_cast
  • 大部分运算符可以通过成员函数或者非成员函数重载,但是如下的运算符只能通过成员函数重载
    • =
    • ()
    • []
    • ->

3.友元

通常情况下,共有类方法是访问类的私有变量的唯一方法。但是有时候这种限制太过严格。为此C++提供了另一种访问形式:友元

  • 友元函数
  • 友元类
  • 友元成员函数

本节的重点是友元函数

编译器转换重载形式的表示法后,需要记住的一点是左侧的操作数应是调用对象。解决这个问题就需要使用友元。

创建友元函数的第一步是将其类型放在类声明中,并在声明前加上关键字friend:

friend Time operator*(double m, const Time & t); // goes in class declaration

注意两点:

  1. 虽然operator*()函数在类声明中,但它不是成员函数,因此不能用成员运算符来调用
  2. 虽然operator*()不是成员函数,但它与成员函数访问权限相同
  3. 在定义的时候不要使用friend关键字

定义如下:

	Time operator*(double m, const Time & t) // friend not used in definition
	{
		Time result;
		long totalminus = t.hours * mult * 60 + t.minutes * mult;
		result.hours = totalminus /60;
		result.minutes = totalminus % 60;
		return result;
	}

关于友元函数是否违背OOP数据隐藏原则的问题。应该将友元函数看作类的扩展接口的组成部分。通过使用类方法和友元函数,可以实现两种操作。而且,只有类声明可以决定哪一个函数是友元函数。因此还是由类声明来决定哪些函数可以访问私有数据。

常用的友元: 重载<<运算符

重载 << 运算符,使其可以和cout一起来显示对象的内容。
现在实现一个cout来显示Time类的内容。

方案1: 使用友元函数

	void operator<<(ostream & os, const Time & t)
	{
		os << t.hours << "hours, " << t.minutes << " minutes";
	}

此时operator<< 是Time类的友元函数,不是ostream 对象的友元函数。

方案2: 改变上述的友元函数的返回类型

	ostream & operator<< (ostream & os, const Time & t)
	{
		os << t.hours << " hours, " << t.minutes << " minutes";
		return os;
	}

返回类型是ostream引用。 << 会从左向右依次调用。

4.重载运算符:作为成员函数还是非成员函数

一般来说,非成员函数应为友元函数,这样才能访问类的私有成员变量。对于成员函数来说,其中一个是this指针隐式传递,一个是作为函数参数显示调用。

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

C++不自动转换不兼容的类型。例如 int * p = 10; // type clash.指针和整型不是同一类型。

在类中,对只有一个参数的构造函数可以作为转换函数,实现隐式转换。对于有两个函数的构造函数,除非第二个函数设定为默认参数,否则不能作为转换函数。

由于这个隐式的转换容易出现意想不到的问题,C++中引入关键字explicit,来限定必须显示的来强制类型转换

6 转换函数

定义类对象向普通类型转换的方式.例如下面的转换

	Stoneswt wolfe(285.7);
	double host = double(wolfe); //syntax #1
	double thinker = (double) wolfe; // syntax #2

定义上述的转换行为需要:operator typeName();这种形式

注意几点:

  • 转换函数必须是类方法
  • 转换函数不能指定返回类型
  • 转换函数不能有参数

应该谨慎的使用隐式转换函数,通常是最好选择仅被显式调用时才会执行的函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值