服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++中类的转换函数你了解吗

C++中类的转换函数你了解吗

2022-10-19 13:23itzyjr C/C++

这篇文章主要为大家详细介绍了C++中类的转换函数,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

只有接受一个参数(其他参数有默认值的也算)的构造函数才能作为转换构造函数

在C++中,接受一个参数的构造函数为将类型与该参数相同的值转换为类提供了蓝图。因此,下面的构造函数用于将double类型的值转换为Stonewt类型:

?
1
Stonewt(double lbs) // double转Stonewt的模板

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

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

这一过程称为隐式转换,因为它是自动进行的,而不需要显式强制类型转换。

将构造函数用作自动类型转换似乎是一项不错的特性。然而,当程序员拥有更丰富的C++经验时,将发现这种自动特性并非总是合乎需要的,因为这会导致意外的类型转换。因此,C++新增了关键字explicit,用于关闭这种自动特性。也就是说,可以这样声明构造函数:

?
1
explicit Stonewt(double lbs) // 不允许隐式转换

这将关闭上述示例中介绍的隐式转换,但仍然允许显式转换,即显式强制类型转换:

?
1
2
3
4
Stonewt myCat;
myCat = 19.6; // 不允许,因为Stonewt(double)声明为explicit
myCat = Stonewt(19.6); // OK,一个显示地转换
myCat = (Stonewt)19.6; // OK,原始地显示类型转换

编译器在什么时候将使用Stonewt(double)函数呢?

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

  • 将Stonewt对象初始化为double值时。如:Stonewt st(1.23);
  • 将double值赋给Stonewt对象时。如:Stonewt st; st = 1.23;
  • 将double值传递给接受Stonewt参数的函数时。如:display(Stonewt& st);-> display(1.23);
  • 返回值被声明为Stonewt的函数试图返回double值时。如:Stonewt& go(){ return 1.23; }
  • 在上述任意一种情况下,使用可转换为double类型的内置类型时。如:Stonewt& go() { return 123; }

可以将数字转换为Stonewt对象。可以做相反的转换吗?也就是说,是否可以将Stonewt对象转换为double值,就像如下所示的那样?

?
1
2
Stonewt wolfe(285.7);
double host = wolfe;// ??可以吗??

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

转换函数是用户定义的强制类型转换,可以像使用强制类型转换那样使用它们。例如,如果定义了从Stonewt到double的转换函数,就可以使用下面的转换:

?
1
2
3
4
5
6
Stonewt wolfe(285.7);
double host = double (wolfe);    // syntax #1
double thinker = (double) wolfe; // syntax #2
也可以让编译器来决定如何做:
Stonewt wells(20, 3);
double star = wells; // 隐式使用转换函数

编译器发现,右侧是Stonewt类型,而左侧是double类型,因此它将查看程序员是否定义了与此匹配的转换函数。(如果没有找到这样的定义,编译器将生成错误消息,指出无法将Stonewt赋给double。)

创建一个转换函数,转换为typeName类型,需要使用这种形式的转换函数:

operator typeName();// 无返回类型,无参数

请注意以下几点:

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

在类的头文件定义:

?
1
2
operator int() const;
operator double() const;

实现代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
......
// construct Stonewt object from stone, double values
Stonewt::Stonewt(int stn, double lbs) {
    stone = stn;
    pds_left = lbs;
    pounds = stn * Lbs_per_stn + lbs;
}
......
// conversion functions
Stonewt::operator int() const {
    return int(pounds + 0.5);
}
Stonewt::operator double() const {
    return pounds;
}

使用:

?
1
2
3
4
5
6
Stonewt poppins(9, 2.8);// 9 stone, 2.8 pounds
double p_wt = poppins;// implicit conversion
cout << "Convert to double => ";
cout << "Poppins: " << p_wt << " pounds.\n";
cout << "Convert to int => ";
cout << "Poppins: " << int(poppins) << " pounds.\n";
?
1
2
Convert to double => Poppins: 128.8 pounds.
Convert to int => Poppins: 129 pounds.

原则上说,最好使用显式转换,而避免隐式转换。在C++98中,关键字explicit不能用于转换函数,但C++11消除了这种限制。因此,在C++11中,可将转换运算符声明为显式的:

?
1
2
3
4
5
6
class Stonewt {
    ...
    // 转换函数
    explicit operator int() const;
    explicit operator double() const;
};

有了explicit声明后,在显式强制转换时才调用这些运算符。

另一种方法是,用一个功能相同的非转换函数替换该转换函数即可,但仅在被显式地调用时,该函数才会执行。也就是说,可以将:

?
1
2
3
Stonewt::operator int() { return int (pounds + 0.5); }
替换为:
int Stonewt::Stone_to_Int() { return int (pounds + 0.5); }

这样,下面的语句:

?
1
2
3
4
int plb = poppins; // 非法
int plb1 = (int) poppins;// 合法
int plb2 = int(poppins);// 合法
int plb3 = poppins.Stone_to_Int(); // 合法

应谨慎地使用隐式转换函数。通常,最好选择仅在被显式地调用时才会执行的函数。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容! 

原文链接:https://blog.csdn.net/itzyjr/article/details/123448216

延伸 · 阅读

精彩推荐
  • C/C++Seesion在C++服务端的使用方法

    Seesion在C++服务端的使用方法

    这篇文章主要介绍了Seesion在C++服务端是怎么使用的?本文给出了解决方案和实例代码供大家参考,需要的朋友可以参考下...

    CPP后台服务器开发7352021-08-19
  • C/C++C语言中的文件结构类型FILE

    C语言中的文件结构类型FILE

    在c语言中的文件概述一文中我们说过在c语言中有两种类型的文件:ASCII文件和二进制文件。ASCII文件很简单就能搞定,新建一个txt文件,然后随便写点内容...

    知蚁博客5372020-10-18
  • C/C++使用C++绘制GDI位图的基本编写实例

    使用C++绘制GDI位图的基本编写实例

    这篇文章主要介绍了使用C++绘制GDI位图的基本编写实例,一般来说适用于Windwos下的C++的GUI编程,需要的朋友可以参考下...

    mig_davidli10202021-03-18
  • C/C++C语言关系运算符实例详解

    C语言关系运算符实例详解

    本文主要介绍C语言的关系运算符的知识,这里提供实例代码以便参考,希望能帮助有需要的小伙伴...

    C语言教程网8242021-04-12
  • C/C++VC中控制台程序创建窗口的实例方法

    VC中控制台程序创建窗口的实例方法

    在本篇文章里小编给大家分享的是关于VC中控制台程序创建窗口的实例方法及相关代码内容,有需要的朋友学习下吧。...

    jobsxiao5942022-03-09
  • C/C++C++实现读入二进制数并转换为十进制输出

    C++实现读入二进制数并转换为十进制输出

    本文给大家介绍的是一则使用C++实现读入二进制数并转换为十进制输出的代码,实现起来其实非常简单,C++本身就提供了二进制类库的,大家看代码吧,简...

    C++教程网11652021-02-22
  • C/C++详解C++编程中对二进制文件的读写操作

    详解C++编程中对二进制文件的读写操作

    这篇文章主要介绍了C++编程中对二进制文件的读写操作,是C++入门学习中的基础知识,需要的朋友可以参考下...

    C++教程网12452021-03-15
  • C/C++C语言应用领域分析

    C语言应用领域分析

    在本篇文章里小编给各位分享的是关于C语言应用领域分析内容,有兴趣的朋友们可以学习下。...

    51CTO9092021-08-26