C++ 重载转换运算符
Posted
技术标签:
【中文标题】C++ 重载转换运算符【英文标题】:C++ Overloading Conversion Operators 【发布时间】:2012-04-23 13:19:42 【问题描述】:我正在尝试创建一个允许隐式转换为某些内置类型的类,例如 unsigned long int 并且因为我试图尽可能正确地执行此操作(这是我在 C++ 中的第一个重要项目),所以我有遇到一个关于 const 正确性的奇怪问题:
这行得通:
#include <iostream>
class CustomizedInt
private:
int data;
public:
CustomizedInt();
CustomizedInt(int input);
operator unsigned long int () const
unsigned long int output;
output = (unsigned long int)data;
return output;
;
CustomizedInt::CustomizedInt()
this->data = 0;
CustomizedInt::CustomizedInt(int input)
this->data = input;
int main()
CustomizedInt x;
unsigned long int y = x;
std::cout << y << std::endl;
return 0;
但是这个:
#include <iostream>
class CustomizedInt
private:
int data;
public:
CustomizedInt();
CustomizedInt(int input);
operator unsigned long int () const;
;
CustomizedInt::CustomizedInt()
this->data = 0;
CustomizedInt::CustomizedInt(int input)
this->data = input;
CustomizedInt::operator unsigned long()
unsigned long int output;
output = (unsigned long int)data;
return output;
int main()
CustomizedInt x;
unsigned long int y = x;
std::cout << y << std::endl;
return 0;
在 Visual Studio 2010 中给我这个错误:error C2511: 'CustomizedInt::operator unsigned long(void)' : overloaded member function not found in 'CustomizedInt'
现在,如果我从运算符定义中删除关键字 const,一切正常。这是一个错误吗?我读到我应该在每个(公共)方法/运算符之后使用 const 关键字,以便清楚地表明它不会以任何方式改变当前对象。
另外,我知道定义这样的运算符可能是不好的做法,但我不确定我是否完全理解相关的注意事项。有人可以概述一下吗?只定义一个名为 ToUnsignedLongInt 的公共方法会更好吗?
【问题讨论】:
【参考方案1】:函数签名与函数定义不匹配。
operator unsigned long int () const;
和
CustomizedInt::operator unsigned long() ...
^^^
const missing
在这种情况下,您应该将转换运算符标记为const
,因为它不会影响对象的内部状态。
另外,使用构造函数初始化列表来初始化你的成员变量。
CustomizedInt::CustomizedInt()
: data()
CustomizedInt::CustomizedInt(int input)
: data(input)
【讨论】:
好的,谢谢!出于某种原因,我认为我不需要在实现中重复后置的 const ......关于构造函数,是的,初始化列表很有用,但是,在我的实际实现中,数据具有复杂类型,并且构造函数初始化列表的实现有点过于复杂... @MihaiTodor 如果data
有一个复杂的类型,我会说这是使用初始化列表而不是赋值的更多理由。 C++ FAQ 解释了为什么这是一种好的做法,并列出了该规则的一些例外情况。
好吧,我完全同意,但是如果您需要调用某些函数来初始化该数据,您会怎么做?我正在使用 GMP 库,数据类型为 mpz_t,需要使用 mpz_init(...) 进行初始化。如何对初始化列表中的数据调用 mpz_init 函数?
@MihaiTodor 在这种情况下你不能;这就是我们为使用 C 库付出的代价 :-)
是的,同意 :) 无论如何,在我完成这个项目后,我希望我会对 C++ 感到更舒服,因为我的背景主要是脚本语言和 C#,所以我接受它慢慢来。【参考方案2】:
您可以从声明中删除const
,但您几乎可以肯定想要做的是添加它到定义中:
CustomizedInt::operator unsigned long() const
unsigned long int output;
output = (unsigned long int)data;
return output;
【讨论】:
好吧,但是如果这个操作符的实现比我的简单例子大呢?不想在header中添加10行实现代码,所以想在类外实现... @michael85:保持标题不变。只需在您实现它的地方添加const
。两个签名需要匹配。【参考方案3】:
是的,如果您的成员函数不影响对象的逻辑状态,那么您确实应该使用const
对其进行后缀,以便编译器强制执行。
但是这种情况下,还需要在定义函数体的时候加上const
!
【讨论】:
【参考方案4】:您只需将相同的函数原型复制到实现中。 即。
CustomizedInt::operator unsigned long int() const
【讨论】:
以上是关于C++ 重载转换运算符的主要内容,如果未能解决你的问题,请参考以下文章