C++——隐式类型转换
创始人
2024-04-16 09:59:01
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 关键字

相关内容

热门资讯

起诉闺蜜借款被驳回?平远法院审... 近日,平远法院审理了一起民间借贷纠纷。原告小洁起诉闺蜜小青,要求归还6000元借款,并提交了微信转账...
广西“上里西游记”表演团队走红... 在“上里西游记”的直播间,身穿红袈裟、骑着白马的“唐僧”跟着“孙悟空”和“猪八戒”走在前面,“沙和尚...
政策组合拳助力“十五五”良好开... 岁末年初,政策窗口期至关重要。 中央经济工作会议部署落定,国家发展改革委已率先行动,抢抓时间窗口,主...
思创医惠:收到杭州市公安局《移... 每经AI快讯,12月31日,思创医惠(300078.SZ)公告称,公司收到杭州市公安局出具的《移送审...
明星电力:员工生育严格执行国家... 有投资者在互动平台向明星电力提问:“您好,请问公司是否针对员工生育或育儿设有相关的福利或激励政策? ...
高科技产业商业秘密保护的挑战与... 一、高科技产业商业秘密纠纷频发 智能驾驶、芯片、动力电池等高科技产业,商业秘密纠纷频发。2025年7...
百利科技(603959)披露公... 截至2025年12月31日收盘,百利科技(603959)报收于5.74元,较前一交易日下跌1.88%...
2025年山西破获经济犯罪案件... 中新网太原12月31日电 (记者 李庭耀)记者31日从山西省公安厅获悉,2025年,山西警方累计破获...
澄星股份:为员工提供符合国家法... 有投资者在互动平台向澄星股份提问:“您好,请问公司是否针对员工生育或育儿设有相关的福利或激励政策? ...
成都市新都区举行劳动纠纷处置比... 近日,2025年“新工司南”主题交流活动暨成都市新都区劳动纠纷处置比武竞赛在四川科伦药业股份有限公司...