使用类知识点总结

前面本人博客下已经总结了,如何定义一个用于表示对象的数据类型和对数据类型所执行的操作。还学习了,用于管理类对象的创建和删除的构造函数和析构函数。

运算符重载及其重载限制

运算符重载

1.运算符重载是一种形式的C++多态。
2.

district2 = sid + sara;
可以用下面的表达式来解释
district2 = sid.operator+(sara);

这里sid对象隐式的调用了operator+,显示的调用了sara对象。
3.将参数声明为引用的目的是提高效率,因为如果值传递的话会先创建副本,然后在进行赋值。
4.

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

返回值不能是引用。因为sum是出于内部的局部变量,当程序执行完后将会自动释放。这个时候如果返回引用就会造成引用指向的地址不明确。
警告:不要返回指向局部变量或者临时对象的引用。函数执行完毕后,局部变量和临时对象将消失,引用将指向不存在的数据。
5.当在类中重载了+运算符时,两个对象使用+运算符时,第一个是隐式调用+运算符的对象,第二个是对象参数。
6.可以多个同类对象相加,因为+是从左到右运算符。每次调用后都返回这个类的对象继续调用+运算符。

运算符重载限制

1.重载后的运算符必须至少有一个操作符是用户定义类型。为了防止用用户重载标准数据类型的运算符。
2.使用运算符时不能违反原有运算符的语法规则,以及运算符的优先级顺序不能改变。
3.不能创建新的运算符
4.还有一些运算符不能重载。
5.大多数运算符都可以通过成员函数和非成员函数进行重载,但是 = () [] ->只能通过成员函数进行重载。

友元

为什么会有友元:个人理解:由于成员函数重载双运算符的时候,只能通过对象调用重载运算符。但是如果运算符左侧不是对象,右侧才是对象,那么这个时候重载的运算符也就没有用了。所以这个时候诞生了友元函数。

1.友元有三种:友元函数,友元类,友元成员函数。
2.注意:如果要为类重载运算符,并将非类的一项作为第一个操作数。则可以用这个友元函数去反转操作数的顺序。
3.<<运算符常用友元函数。
注意事项:如果用成员函数来重载<<运算符的话,eg:

class Time
{
....
};
void Time::operator<<(ostream & os)
{
...
}
Time t1;
ti<<cout;

这样就跟平常的<<运算符相反了。所以采取友元函数

void operator<<(ostream & os,Time & t)
{...}
cout << t1;

这样看着就很舒服!
6.第5点的友元函数cout << trip 应使用cout对象本身,而不是它的拷贝,因此该函数按引用传递对象。Time对象可以按值或引用来传递,按引用传递使用的内存和时间都比按值传递少。
7.要实现多个对象连续相等可以返回对象+&.
8.只有在类声明中的原型使用friend关键字。除非函数定义也是原型,否则不能在函数定义中加friend关键字。
9.重载运算符可以是成员函数也可以是非成员函数,非成员函数应该是友元函数,成员函数比非成员函数要少一个操作数,而这个操作数就是调用这个成员函数的对象。
10.在重载的时候只能在重载成员函数和重载非成员函数中选择一个,否则就会造成二义性。(这里提一句在对象转换的时候会用到单参数的构造函数和友元函数,实现由对象转化。)
11.类非常适用于可以多种形式表示一个东西,例如,带方向的矢量,可以用x,y来表示,也可以用长度加弧度来表示。在这里可以设置一个状态成员,在构造函数中使用这个状态成员的时候,就可以根据状态成员去判断采用的那种方式去表示这个类,并且在每个状态下都隐含的设置了内联函数去求其他表示方式的值。例如你设置了状态成员,用x,y表示一个矢量,相应构造函数就会根据i的状态成员来保存x,y,并且还会计算出相应的长度和弧度。这个求长度和弧度的方法就是内联函数。
12.如果方法通过计算得到一个新的类对象,则应考虑是否可以使用类构造函数来完成这种工作,这样做可以避免麻烦,还确保了新的对象是按照正确的方式创建的。例如,将两个矢量相加得到新的一个矢量,可以在函数内部将最后的量传递给矢量的构造函数中,这样新的矢量又满足了类的构造函数。
13.在类中重载了的运算符也是可以继续重载,只要满足重载条件即可。
14.rand()%360表示的是0~359中的一个随机数。但是如果没有加srand(time(0)),那么这个随机数是不变的。而为什么加了srand(time(0))之后它就会变呢?是因为srand()提供随机数种子,它的工作机理是,提供一个随机数序列并覆盖之前的随机数序列。而time(0)的返回值是拿来设置随机数种子的,time(0)返回当前的时间。头文件cstdlib包含了rand和srand的原型。ctime包含了time的原型。

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

1.类的自动转换也被称为隐式转换。例如

class Stonewt{
Stonewt(double ls){......};
};
Stonewt mycat;
mycat = 19.5;

这种是程序将使用构造函数Stonewt(double)来创建一个临时对象,并将19.5作为初始化值,随后采用逐成员赋值方式将该临时对象的内容复制到myCat。这是隐式转化(只有一个参数的构造函数才能作为转化函数)但是这样做有时候会很隐蔽,导致出错的时候十分难以发现,所以产生了explicit用于关闭这种隐式转缓,用explicit声明表示了只能进行显示转换。
2.隐式类型转换还有一个缺点就是,当类中有着多个一种参数的构造函数时,转换将导致二义性,它会让编译器无法得知到底进行那种转换。
3.前面讲了由基本类型到类的转换,那么类到基本类型的转换呢?就需要用转换函数 operator typeName();
注意以下几点:
转换函数必须是类方法;
转换函数不能指定返回类型;
转换函数不能有参数。
4.最好避免隐式转化,采取显示转换

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值