11 使用类(类设计技术)

轻松地使用这种语言。不要觉得必须使用所有的特性,不要在第一次学习时就试图使用所有的特性

0 日志

2022/04/18 起笔
2022/04/21 补充修改2.1友元引入原因

1 运算符重载

operatorop(argument -list) 注意op必须是有效的C++运算符

1.1 重载举例


1)函数原型的区别
Time Sum(const Time & t) const;
Time operator+(const Time & t) const;


2)函数定义的区别
Time Time::Sum(const Time & t) const{
  Time sum;
  sum.minutes = minutes + t.minutes;
  sum.hours = houts + t.hours + sum.minutes/60;
  sum.minutes %= 60;
  return sum;
}

Time Time::operator+(const Time & t) const{
 Time sum;
 sum.minutes = minutes + t.minutes;
 sum.hours = hours + t.hours+ sum.minutes/60;
 sum.minutes %= 60;
 return sum;	
}

3)函数调用的区别
total = coding.sum(fixing);
total = coding + fixing;  运算符表示法
total = coding.operator+(fixing); 函数表示法

4)链式表达
t4 = t1.sum(t2.sum(t3));
t4 = t1 + t2 + t3;
t4 = t1.operator+(t2+t3);
t4 = t1.operator+(t2.operator+(t3));  +是从左到右结合的运算符

1.2 重载限制

  • 至少有一个操作数是用户定义的类型(防止用户为标准类型重载运算符)
  • 不能违反运算符原来的句法规则(不能将%运算符重载为使用也给操作数)
  • 不能修改运算符的优先级
    C++中运算符的优先级
  • 不能创建新的运算符
  • 不能重载的运算符
sizeof
. 成员运算符
.* 成员指针运算符
:: 作用域解析运算符
?: 条件运算符
typeid 一个RTTI运算符(Run-Time Type Identification,运行时类型识别)
const_cast 以下皆为强制类型转换运算符
dynamic_cast
reinterpret_cast
static_cst 
  • 只能通过成员函数重载的运算符
= 赋值运算符
() 函数调用运算符
[] 下标运算符
-> 通过指针访问类成员的运算符

1.2.1 有的运算符只能通过成员函数重载?

关于有些运算符只能用成员函数重载

2 友元

2.1 引入原因

首先介绍分类:

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

为何需要友元:
重载运算符*时,若为普通的成员函数调用,需要注意参数的顺序

A=B*2.75;
A=2.75*B;
无法兼得
解决方案:告诉每个使用的人只能按一种格式使用
即服务器友好-客户警惕的方案 server-friendly,elinet-beware

而非成员函数调用匹配,其不是由对象调用的
其使用的所有值都是显式参数
可以按所需的顺序调用匹配

Time operator*(double m, const Time & t);
A = operator*(2.75, B);
或者
A =2.75*B;

但问题:非成员函数不能直接访问类的私有数据
故产生了友元函数

2.2 创建友元

1)原型放入类声明中,并在前加上关键字friend

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

2)编写函数定义,注意不需要::限定符,不要使用关键字friend

Time operator*(double m , const Time & t){
	Time result;
	long totalminutes = t.hours * m * 60 + t.minutes * m;
	注意这里访问了对象的私有成员
	...
}

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

通过使用友元函数和类方法,可以用同一个用户接口表达两种操作,它们只是表达类接口的两种不同机制

实际上,也可以将友元函数编写为非友元函数

Time operator*(double m, Time t){
	return t*m;
}
原来的版本显式访问t.minutes等等,必须是友元,这个版本让成员函数处理私有值
因此不必是友元

而将此版本作为友元函数也不错,它将作为正式类接口的组成部分
以后如果发现需要函数直接访问私有数据,则只要修改函数定义即可,不必修改类原型

2.2.1 重载<<运算符

背景知识:cout是一个ostream对象,对于每种基本类型,ostream类声明中都包含了相应的重载的operator<<()定义

目的:使cout能识别对象

2.2.1.1 版本一:必须使用友元函数

原因:如果使用Time成员函数,Time对象将是第一个操作数

trip<<cout; 太诡异了

正确重载:

void operator<<(ostream & os,const Time & t){
	os<<t.hous<<"hours,"<<t.minutes<<" minutes,";
}
注意这里:
1)应该使用cout对象本身,而不是拷贝
2)通常情况下,os引用cout对象

使用:
cout<<trip;

注意在这里由于并不直接访问ostream对象的私有成员,所以并不一定必须使ostream类的友元——这很好,意味着不必修订ostream的定义

2.2.1.2 版本二:返回ostream引用对象

原因:前一种版本不允许像通常那样将重定义运算符与cout一起使用

cout<<"//"<<trip;

<<运算符要求左边是一个ostream对象,ostream类中将operator<<()函数实现为返回一个指向ostream对象的引用
修改:

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

2.2.2 成员与非成员的选择

一般非成员函数应该是友元函数
非成员版本的重载运算符函数所需的形参数目与运算符使用的操作数数目相同
成员版本所需的参数数目少一个(其中一个操作数是被隐士第传递的调用对象)

在定义运算符 时,不能同时使用两种格式(通过友元函数反转参数的不算)

对于有些运算符,成员函数是唯一的选择
有时根据类设计,使用非成员函数版本可能更好

3 类的自动转化和强制类型转换?

C++可以自动转换兼容的类型,强制转换不兼容的类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java与对象是Java语言的核心概念之一,理解它们对于Java编程非常重要。以下是一些Java与对象的知识点: 1. 是对象的模板,对象是的实例。 2. 可以包含属性(变量)和方法(函数)。 3. 的属性可以是基本型或对象型。 4. 的方法可以是静态的或实例的。 5. 实例变量和方法可以通过对象访问。 6. 静态变量和方法可以通过名访问。 7. 构造函数是用来创建对象的特殊方法。 8. 可以继承其他,从而获得父的属性和方法。 9. 继承可以实现代码重用和多态性。 10. 接口是一种似于抽象的结构,它定义了一组方法,但没有实现。 11. 实现接口的必须实现接口定义的所有方法。 12. 包是一种组织代码的方式,它可以避免命名冲突。 13. 访问修饰符(public、protected、private)用于限制、属性和方法的访问范围。 14. Java提供了垃圾回收机制,自动回收不再使用的对象。 15. 对象的生命周期由它们的引用决定,当没有引用指向对象时,它们会被垃圾回收器回收。 以上是Java与对象的一些基本知识点,希望能对你有所帮助。 ### 回答2: Java是面向对象编程的基本概念之一。一个是一个模板或蓝图,用于创建具有相同属性和方法的对象。由属性(变量)和方法组成。 对象是的实例化。通过使用new关键字,我们可以创建一个对象并引用它。对象包含定义的属性的具体值。可以通过调用对象的方法来操作和访问对象的属性。 和对象在Java编程中非常重要。它们可以帮助我们模拟真实世界中的问题和实体。以下是一些关于Java和对象的重要知识点: 1. 的声明:在Java中,通过使用关键字class可以声明一个的声明包含的名称和体。 2. 对象的创建:要创建一个对象,我们使用new关键字并调用的构造方法。构造方法被用来初始化对象的属性。 3. 属性和方法:由属性和方法组成。属性是的特征和数据的容器,而方法是用于操作和访问属性的行为。 4. 封装:Java支持数据封装。通过将属性声明为私有,并提供公共的get和set方法,可以保护属性,从而实现数据封装。 5. 继承:继承是面向对象编程中的一种重要概念。通过继承,一个可以从另一个获得属性和方法。Java支持单继承,一个只能继承另一个。 6. 多态:多态是指一个对象可以具有多个形式。在Java中,多态性是通过继承和方法重写实现的。 7. 构造方法:构造方法是的一个特殊方法。它用于创建和初始化对象。 8. this关键字:this关键字用于引用当前对象的属性和方法。 9. static关键字:static关键字用于修饰的成员。静态成员被共享,可以在不创建对象的情况下访问。 10. 包:包用于组织和管理,防止命名冲突。 这些是Java和对象的一些重要知识点。理解和掌握这些知识点可以帮助我们在Java编程中更好地使用和对象,并能够设计和实现复杂的应用程序。 ### 回答3: Java是一种面向对象编程的基本概念。它是用来描述现实世界中具有相同特征和行为的对象的模板。在Java中,可以看作是创建对象的蓝图或者是对象的抽象。包含了对象的属性和方法,通过创建的实例,可以实现对这些属性和方法的访问。 的属性是描述对象特征的变量,也叫做成员变量。可以用来表示对象的状态。的方法是用来描述对象行为的函数,也叫做成员函数。可以用来表示对象的行为。可以有多个属性和方法,通过的实例化可以创建多个对象。 对象是的实例,也就是通过创建的具体个体。对象具备了的特性,可以访问的属性和方法。可以通过new关键字来创建对象,并调用对象的方法。对象可以独立存在,可以具有独立的状态和行为。 和对象是面向对象编程中的核心概念,它们是实现封装、继承和多态的基础。封装是将对象的属性和行为封装在中,通过控制访问权限来实现对象的信息隐藏。继承是通过继承一个父来创建一个新的,并继承父的属性和方法。多态是指一个的实例可以以多种形式来使用,通过继承和实现接口来实现多态。 了解和掌握和对象的知识点对于Java编程非常重要。它是面向对象编程的基础,可以帮助我们更好地理解和设计程序,提高代码的可维护性和可扩展性。掌握和对象的知识点,也是进一步学习Java的面向对象特性和高级编程技术的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值