第十一章 实用类

Posted sungnox

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十一章 实用类相关的知识,希望对你有一定的参考价值。

下面的程序涉及到了类的构造函数,默认构造函数,析构函数,转换函数,友元函数,运算符重载。

 1 //头文件,a.h
 2 #ifndef a_H_//宏名不应以数字打头
 3 #define a_H_
 4 
 5 #include<string>
 6 
 7 class Animal
 8 {
 9 private:
10     std::string animal;
11     int weight;
12     int num;
13 
14 public:
15     Animal();
16     explicit Animal(std::string &, int n = 1, int w = 30);
17     ~Animal();
18     //运算符重载
19     Animal operator+(Animal &aml) const;
20     //友元
21     friend Animal & operator+(Animal &aml, int);
22     //转换函数(C++98中explicit不能用于转换函数,只能用于构造函数)
23     operator std::string() const;
24 
25     void show();
26 
27 };
28 #endif
 1 //类定义
 2 #include "a.h"
 3 #include<string>
 4 #include<iostream>
 5 
 6 Animal::Animal()
 7 {
 8     animal = "none";
 9     num = weight = 0;
10 }
11 
12 Animal::Animal(std::string &aml, int n, int w)
13 {
14     animal = aml;
15     num = n;
16     weight = w;
17 }
18 
19 Animal::~Animal()
20 {
21     std::cout << animal << "->" << num << "->" << weight << "->" << "byb!!" << std::endl;
22 }
23 
24 Animal Animal::operator+(Animal &aml) const
25 {
26     return Animal(aml.animal, aml.num+num, aml.weight+weight);
27 }
28 
29 
30 Animal::operator std::string() const
31 {
32     return animal;
33 }
34 
35 void Animal::show()
36 {
37     std::cout << animal << std::endl << num << std::endl << weight << std::endl;
38 }
39 
40 //友元
41 Animal & operator+(Animal &aml, int n)
42 {
43     aml.num += n;
44     return aml;
45 }
 1 #include<iostream>
 2 #include "a.h"
 3 
 4 int main()
 5 {
 6     {
 7     std::string aml= "tiger";
 8     Animal Tiger0(aml, 30, 1);
 9     Animal Tiger1(aml, 40, 1);
10     Animal Tiger2(aml, 10, 3);
11     Animal tol_Tiger = Tiger0+Tiger1+Tiger2;//调用重载的运算符‘+’
12     tol_Tiger.show();
13     }
14     {
15     std::string aml1= "sheep";
16 //    Animal Sheep = aml1;//单参数构造函数,隐式类型转换(用关键字explicit限定构造函数,将禁止这种隐式转换)
17 //    Sheep.show();
18 
19     Animal Sheep2(aml1);//显示的调用单参数构造函数
20     std::string aml2 = Sheep2;//调用转换函数
21     std::cout << aml2 << std::endl;
22     }
23 
24     {
25     Animal What;//隐式地调用默认构造函数
26     Animal W2 = What +2;//使用友元
27     What.show();
28     }
29 
30     system("pause");
31     return 0;
32 }

 

C++提供了另一种访问权限——友元。

友元有3种:友元函数;友元类;友元成员函数。

本章只涉及到友元函数。

在为类重载二元运算符时常常需要友元。

创建友元

将其原型放在类声明中,并在原型声明前加上关键字friend。

其与成员函数的访问权限相同。

类方法和友元是表达类接口的两种不同机制。

 

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

在C++中,接受一个参数的构造函数为 将类型与该参数相同的值转换成类 提供了蓝图。

即,可以将与构造函数参数类型相同的变量转换为该类对象(隐式转换),C++新增了关键字explicit用于关闭该特性,但仍然允许显式转换。

 

转换函数

构造函数只用于从某种类型到类类型的转换。要进行相反的转换,必须使用特殊的C++运算符——转换函数。

转换函数是用户定义的强制类型转换,可以像使用强制类型转换那样使用它们。

创建转换函数

operator typename();

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

当类定义了两种或更多的转换时,可以使用显式强制类型转换指出要使用哪个转换函数。

 

原则上,最好使用显式转换,而避免隐式转换。

在C++98中,关键字explicit不能用于转换函数,但C++11消除了这个限制,在C++11中可将转换运算符声明为显式的。

 

使用转换函数时的一个问题

设Stock是一个类,其中定义了单参数构造函数Stock(long),并且没有使用关键字explicit限定;而且定义了转换函数operate long();重载了运算符“+”,操作数为Stock类对象。

代码如下:

1 Stock st1(1000);
2 long st2 = 200;
3 Sotck ST;
4 ST = st1 + st2;

那么第四行是先将st1通过转换函数隐式转换为long整型再对long整型进行"+"操作,之后再转换到Stock类对象;还是先将st2通过构造函数隐式转换为Stock类对象再对Stock类对象进行"+"操作?

为避免以上问题在C++98中,最好用explicit限定构造函数禁止隐式转换。

 

以上是关于第十一章 实用类的主要内容,如果未能解决你的问题,请参考以下文章

快学Scala习题解答—第十一章 操作符

构建之法阅读笔记08-第十一章

Python编程:从入门到实践——作业——第十一章(测试代码)

第十一章

第十一章 拟牛顿法

Python笔记·第十一章—— 函数 装饰器