ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

第11章 使用类

2022-07-10 11:35:08  阅读:122  来源: 互联网

标签:11 友元 函数 double 运算符 重载 使用 operator


<c++ primer plus>第六版

目录

11 使用类

11.1 运算符重载

函数重载/函数多态: 定义多个名称相同但特征标不同的函数.
运算符重载是一种形式的c++多态, 将重载的概念扩展到运算符上.

运算符函数, 是一种特殊函数形式, 格式如下:

operatorop(argument-list);

其中op必须是有效的c++运算符, 不能虚构新运算符.

例如

operator+()  //重载+运算符
operator*()  //重载*运算符
operator[]() //重载[]运算符(数组索引运算符)

如下语句:

district2 = sid + sara;          //编译器将使用运算符函数替换上述运算符:
district2 = sid.operator+(sara); //该函数隐式地使用sid, 显式地使用sara.

11.3 友元


通常, 访问类的途径只能通过公有类方法. 但这种限制太严, 所以提供了另外形式的访问权限: 友元.
友元有3种: 友元函数, 友元类, 友元成员函数.


为何需要友元函数:
对于 A = B * 2.75; 转换为 A = B.operator*(2.75);
但 A = 2.75 * B, 由于2.75不是自定义的类对象, 编译器没办法使用成员函数调用来替换该表达式.
解决方法:

  1. 限制只能按 B*2.75方式写, 这样对客户不友好.
  2. 使用非成员函数:
    函数原型: Time operator(double m, const Time & t);
    则 A = 2.75 * B; 替换为 A = operator
    (2.75, B);

但使用非成员函数引发了一个新问题: 常规非成员函数不能直接访问类的私有数据,
于是提出特殊的非成员函数, 它可以访问类的私有成员, 被称为友元函数.


11.3.1 创建友元

//第一步, 将原型放在类声明中, 并加friend关键字.
friend Time operator*(double m, const Time & t);

//第二步, 编写函数定义, 由于不是成员函数, 所以不需要Time::限定符. 且不需要在定义中使用friend关键字.
Time operator*(double m, const Time & t)
{
    Time result;
    ... //访问t的私有数据
    return result;
}

类的友元函数是非成员函数, 但访问权限与成员函数相同.

注意, 只有类声明可以决定哪些函数是友元, 因此类声明仍然控制了哪些函数可以访问私有数据.

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

cout是一个ostream对象, 它能够识别所有c++基本类型(因为对每个基本类型, ostream类声明中都包含了相应的重载的operator<<()定义).

要使cout能识别Time对象, 对<<进行重载, 可以这样显示对象:

cout << trip ;

一般来说, 要重载<<运算符来显示C_NAME的对象, 可以使用一个友元函数, 定义如下:

ostream & operator<<(ostream & os, const C_NAME & obj)
{
    os << ...; //显示对象内容
    return os;
}

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

加法运算重载

成员函数版本 :

Time operator+(const Time & t) const;
T1 = T2+T3 //转换为 T1 = T2.operator+(T3);

非成员函数版本:

friend Time operator+(const Time & t1, const Time & t2); 
T1 = T2+T3 转换为 T1 = operator+(T2, T3);

成员函数版本少一个参数, 这个参数通过this指针隐式地传递.

11.5 再谈重载: 一个矢量类

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

兼容的内置类型的转换

long count = 8;   //将整型值8转换为long类型
double time = 11; //将整型值11转换为double类型
int side = 3.33;  //将双精度值3.33转为整型值3

不兼容类型不能自动转换

int * p = 10; //错误, 不能把整数赋值给指针
int * p = (int *) 10; //正确, 将10强制转为int指针类型(int *), 再将指针赋值给p.

11.6.1 转换函数

Stonewt wolfe(285.7); //double类型转换为Stonewt类型
double host = double(wolfe);     //将Stonewt类型转换为double类型, 语法1.
double thinker = (double) wolfe; //将Stonewt类型转换为double类型, 语法2.

Stonewt wells(20, 3);
double star = wells; //左侧double, 右侧Stonewt, 编译器将寻找转换函数(如果找不到, 将报错)

转换函数的定义方法:

operator typeName();

如:

operator double(); //转换为double类型的函数

注意:

  1. 转换函数必须是类方法;
  2. 转换函数不能指定返回类型;
  3. 转换函数不能有参数;
#ifndef STONEWT1_H_
#define STONEWT1_H_
class Stonewt
{
...
public:
    operator int() const;
    operator double() const;
}

#endif


Stonewt::operator int() const //最后一个const表示是const函数, 不修改类成员
{
    return int(pounds + 0.5);
}

11.6.2 转换函数和友元函数

标签:11,友元,函数,double,运算符,重载,使用,operator
来源: https://www.cnblogs.com/gaiqingfeng/p/16462821.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有