C++——隐式类型转换
创始人
2024-03-14 16:43:34
0

隐式类型转换(构造函数的隐式调用)

先看一下隐式类型转换如何发生吧:

#include 
using namespace std;class point {public:int x,y;point(int x=0, int y=0):x(x),y(y) {}
}void displayPoint(const point &p)
{cout << "( " << p.x << "," << p.y << " )";
}int main()
{displayPoint(1);point p = 1;
}

我们定义了一个很简单的point类,它的构造函数使用了默认参数(int x=0, int y=0),这时main函数里的两句都触发了构造函数的隐式调用

如果构造函数不使用默认参数,会在编译时报错

很显然,函数displayPoint需要的是point类型的参数,而我们传入一个int数据,这个程序能够成功运行,并且成功输出(0,0)说明隐式调用了构造函数。另外需要注意的是,在对象刚刚定义的时候,使用赋值操作符=,调用的是构造函数,而不是operator=运算符

这种悄然发生的事情,有时可以带来便利,让你的程序可以继续运行,而更多的会带来很多意想不到的结果,explict关键字用来避免这样的情况发生

explicit 关键字

c++11中对explicit的解释为指定构造函数或转换函数(operator type())为显示,即它不能用于隐式转换和复制初始化

在上面point示例中,构造函数被explicit修饰后,就不能被隐式调用了,主函数中的两句声明定义将不会通过编译

能用就用

如果我们能预料某种情况的发生,就不要把这个情况控制权交给编译器。即使没有加explicit的构造函数,我们也应该先声明point p(1),再把p作为参数传递给displayPoint函数

Effective C++中也写到

被声明为explicit的构造函数通常比non-explicit兄弟更受欢迎,因为它们禁止编译器执行非预期(往往也不被期望)的类型转换,除非我有一个好理由允许构造函数被用于隐式类型转换,否则我会把它声明为explicit,我鼓励你遵循同样的政策

operator用于隐式类型转换

C++中的operator主要有两种作用,一是操作符重载,二是自定义对象类型的隐式转换。在上面提到的point类中,我们提到如果构造函数没有默认参数,隐式转换的时候就会编译出错,但是如果我们利用operator的第二个作用,就可以自定义隐式转换类型。

#include 
#include 
using namespace std;class point {public:point(int x, int y):x(x),y(y) {cout << "constructor" << endl;}bool operator()(int x, int y) {cout << "opearator overload" << endl;return x>this->x && y>this->y;}operator string() {cout << "type convert" << endl;string str = "(" + x;str += "," + y;str += ")";return str;}private:int x,y;
};int main()
{// part1point p1(5,6);if(p1(10,9)){cout << "point(10,9) is larger than  point(5,6)" << endl;}// part2string str(p1);cout << str;
}

运行结果如下:

主函数的part1调用的是operator的重载作用,我们主要探讨part2的隐式转换作用。我们往string类的构造函数中传递的point类,显然string类中必然没有以point类为参数的构造函数,但是从运行结果来看,这次构造是成功的。

如果string类有默认参数的构造函数,那么string str(p1)会隐式调用该默认参数的构造函数来构造string。对于没有默认参数的构造函数情况下,类的隐式类型转换,是使用一个其他类型构造当前类的临时对象,并用此临时对象来构造当前对象,这种转换必须有其他类型的构造函数支持;而operator算子的隐式类型转换,就是使用当前类型对象生成另一个类型的对象(正好与没有默认参数构造函数情况下,类的隐式转换相反),这种转换必须有operator算子的支持。

在这个例子中,string str(p1)是将point类对象转换成string类对象,使用的是string类的隐式构造(转换),string类不存在有默认参数的构造函数,也不存在以point类为参数的构造函数,那么string类就需要去point类中去找以operator算子修饰的将point类转为string类的转换函数,并调用该函数,最终返回的string临时对象,被string类用来拷贝构造成一个新的string对象str

参考文章
C++ explicit 关键字

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...