C++类类型转换中rec(polar p)构造函数触发机制疑问
运行原理解释
你遇到的是C++的隐式类型转换规则,整个过程的逻辑非常明确:
- 你在
rec类中定义的rec(polar p)属于转换构造函数:只要构造函数仅接收一个其他类型的参数,且没有被explicit关键字修饰,就支持从参数类型到当前类类型的隐式转换。 - 执行
r1 = p1时,编译器首先会检查你有没有为rec类重载rec& operator=(const polar&)赋值运算符,发现没有之后,会尝试将右值p1隐式转换为rec类型的临时对象,这一步就会自动调用你写的rec(polar p)构造函数。 - 转换完成后,编译器会调用自动生成的默认拷贝赋值运算符
rec& operator=(const rec&),把临时rec对象的成员值拷贝给已存在的r1对象,最后临时对象被销毁。 - 整个执行过程等效于
r1 = rec(p1);,所以你会看到转换构造函数被触发。
额外提醒:你代码中传入的角度是45角度值,但C++标准库的cos、sin函数接收的是弧度值,实际运行的计算结果会不符合预期,可以自行做单位转换修正。
更清晰可控的类型转换实现方式
推荐三种可读性更强、也更容易避免隐式转换bug的实现方案:
- 显式调用转换构造函数,禁用隐式转换
给转换构造函数加上explicit关键字:explicit rec(polar p),此时r1 = p1会直接编译报错,强制你必须写r1 = rec(p1)显式说明类型转换,完全避免意料之外的隐式转换问题。 - 重载对应类型的赋值运算符
在rec类中新增polar类型的赋值运算符重载,不需要生成临时对象,效率更高逻辑也更直接:rec& operator=(const polar& p) { float rv = p.getr(); float av = p.getang(); x = rv * cos(av); y = rv * sin(av); return *this; } - 在源类型中定义转换运算符
也可以把转换逻辑封装在polar类中,首先前向声明class rec;,之后在polar的public成员中添加转换函数:
这种方案适合转换逻辑不需要访问目标类私有成员的场景。operator rec() const { return rec(r * cos(ang), r * sin(ang)); }
内容的提问来源于stack exchange,提问作者Samar Shrestha
相关产品推荐
相关产品推荐

