最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

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

来源:博客园

程序清单11.16 stonewt.h

#pragma once//stone.h -- Stonewt类声明#ifndef STONEWT_H_#define STONEWT_H_class Stonewt{private:enum {Lbs_per_stn = 14};//pounds per stoneint stone;//whole stonedouble pds_left;//fractional poundsdouble pounds;//enrire weight in poundspublic:Stonewt(double lbs);//constructor for double poundsStonewt(int stn, double lbs);//constructor for stone, lbsStonewt();//default constructor~Stonewt();void show_lbs() const;//show weight in pounds formatvoid show_stn() const;//show weight in stone format};#endif 

说明:这个类并非真的需要声明析构函数,因为自动生成的默认构造函数就很好。另外,提供显示的声明可以为以后做好准备,以防必须定义构造函数。


(资料图片)

程序清单11.17 stonewt.cpp

#pragma warning(disable:4996)#define _CRT_SECURE_NO_WARNINGS 1//stone.cpp -- Stonewt methods#include using std::cout;#include "stonewt.h"//construct Stonewt object from double valueStonewt::Stonewt(double lbs)//constructor for double pounds{stone = int(lbs) / Lbs_per_stn;pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);pounds = lbs;}Stonewt::Stonewt(int stn, double lbs)//constructor for stone, lbs{stone = stn;pds_left = lbs;pounds = stn * Lbs_per_stn + lbs;}Stonewt::Stonewt()//default constructor, wt = 0{stone = pounds = pds_left = 0;}Stonewt::~Stonewt(){}void Stonewt::show_lbs() const//show weight in pounds format{cout << pounds << " pounds\n";}void Stonewt::show_stn() const//show weight in stone format{cout << stone << " stone, " << pds_left << " pounds\n";}

因为Stonewt对象表示一个重量,所以可以提供一些整数或浮点值转换为Stonewt对象的方法。在C++中,接受一个参数的构造函数支持将类型与该参数相同的值转换为类。下面的构造函数用于将double类型的值转换为Stonewt类型:

Stone(double lbs);

也就是说,可以编写这样的代码:

Stonewt myCat;//创建一个Stonewt对象myCat = 19.6;//使用Stonewt(double)将19.6转换为Stonewt

程序员将使用构造函数Stonewt(double)来创建一个临时Stonewt对象,并将19.6作为初始化值。随后,采用逐成员赋值方式将该临时对象的内容复制到myCat中。这一过程称为隐式转换,因为它是自动进行的,而不需要显式强制类型转换。

只接受一个参数的构造函数才能作为转换函数。下面的构造函数有两个参数,因此不能用来转换类型:

Stonewt(int stn, double lbs);

然而,如果给第二个参数提供默认值,它便可以用于转换int:

Stonewt(int stn, double lbs = 0);

有时会导致意外的类型转换。因此,C++新增了关键字explicit,用于关闭这种自动类型。也就是说,可以这样声明构造函数:

explicit Stonewt(double lbs);

这将关闭上述示例的隐式转换,但仍然可以显示强制类型转换:

Stonewt myCat;myCat = 19.6;mycat = Stonewt(19.6);mycat = (Stonewt) 19.6;

注意:只接受一个参数的构造函数定义了从参数类型到类类型的转换。如果使用关键字explicit限定了这种构造函数,则它只能用于显式转换,否则也可以用于隐式转换。

编译器将使用Stonewt(double)函数的时

如果在声明中使用了关键字explicit,则Stonewt(double)将只用于显式强制类型转换,否则还可以用于下面的隐式转换。

●将stonewt对象初始化为double值时

●将double值赋值给Stonewt对象时

●将double传递给接受Stonewt参数的函数时

●返回值被声明为Stonewt的函数试图返回double值时

●在上述任意一种情况下,使用可转换为double类型的内置类型时

当且仅当转换不存在二义性时,才会进行这种二步转换。

程序清单11.18 stone.cpp

#pragma warning(disable:4996)#define _CRT_SECURE_NO_WARNINGS 1//stone.cpp -- 用户定义版本//和stonewt.cpp联合编译#include using std::cout;#include "stonewt.h"void display(const Stonewt& st, int n);int main(){Stonewt incognito = 275;//使用构造函数初始化Stonewt wolfe(285.7);//等价于Stonewt wolfe = 285.7;Stonewt taft(21, 8);cout << "The celebrity weighed ";incognito.show_stn();cout << "The decetive weighed ";wolfe.show_stn();cout << "The President weighed ";taft.show_lbs();incognito = 276.8;//使用构造函数转换taft = 325;//等价于taft = Stonewt(325);cout << "After dinner, the celebrity weighed ";incognito.show_stn();cout << "After dinner, the President weighed ";taft.show_lbs();display(taft, 2);cout << "The wrestler weighed even more.\n";display(422, 2);cout << "No stone left unearned\n";system("pause");return EXIT_SUCCESS;}void display(const Stonewt& st, int n){for (int i = 0; i < n; i++){cout << "Wow! ";st.show_stn();}}

输出:

The celebrity weighed 19 stone, 9 poundsThe decetive weighed 20 stone, 5.7 poundsThe President weighed 302 poundsAfter dinner, the celebrity weighed 19 stone, 10.8 poundsAfter dinner, the President weighed 325 poundsWow! 23 stone, 3 poundsWow! 23 stone, 3 poundsThe wrestler weighed even more.Wow! 30 stone, 2 poundsWow! 30 stone, 2 poundsNo stone left unearned请按任意键继续. . .

程序说明:

当构造函数只接受一个参数时,可以使用下面的格式来初始化类对象:

Stonewt incognito = 275;

这等价于前面介绍过的另外两种格式:

Stonewt incognito(275);Stonewt incognito = Stonewt(275);

接下来,请注意程序清单11.18的下面两条语句:

incognito = 276.8;taft = 325;

第一条赋值语句使用接受double参数的构造函数,将276.8转换为一个Stonewt值,这将incognito的pound成员设置为276.8。因为该语句使用了构造函数,所以还将设置stone和pds_left成员。同样,第二条赋值语句将一个int值转换为double类型,然后使用Stonewt(double)来设置全部3个成员。

注意:

display(422, 2);

display()原型表示,第一个参数是Stone对象(Stonewt 和Stonewt &形参都与Stonewt实参匹配)。遇到int参数时,编译器查找构造函数Stonewt(int),以便将该int值转换为Stonewt类型。没找到,于是匹配率Stonewt(double)。

关键词: 构造函数 强制类型转换 也就是说