我遇到了一个奇怪的c++运算符。
http://www.terralib.org/html/v410/classoracle_1_1occi_1_1_number.html#a0f2780081f0097af7530fe57a100b00d
class Number {
..
operator unsigned short () const;
};
我将此操作员称为:a数字(..);unsigned short b=a.operator unsigned short();
这是有效的,但我不明白它是如何工作的。
首先,这个运算符没有返回值。seconds,a.operator unsigned short()对我来说真的很奇怪。有什么更好的方法来调用它?
如果我打电话:无符号短b=a;接线员会接到电话吗?关于这一点,有什么c++标准可以说吗?
函数是一个用户定义的转换运算符。更多详细信息,请访问http://en.cppreference.com/w/cpp/language/cast_operator.
你说
此运算符没有返回值。秒,
用户定义的转换运算符的返回值是显式类型。在您的情况下,返回类型为unsigned short
。
你问:
有什么更好的方法来称呼它?
您可以执行显式强制转换来调用该函数。
Number n;
unsigned short s = (unsigned short)v;
当编译器需要转换时,也会调用它。
void foo(unsigned short s) {}
Number n;
foo(n); // Number::operator unsigned short() is called to cast
// n to an unsigned short.
你问:
如果我呼叫:
unsigned short b = a;
,接线员会被呼叫吗?关于这一点,有什么c++标准可以说吗?
是的。调用用户定义的运算符函数。
以下是C++标准草案(N3337)的相关章节:
12.3.2转换功能
1类
X
的一个成员函数,它没有具有形式名称的参数示例:
struct X { operator int(); }; void f(X a) { int i = int(a); i = (int)a; i = a; }
在这三种情况下,赋值都将由X::运算符int()转换结束示例]
这是转换运算符。转换函数通常具有的一般形式
operator type() const;
其中CCD_ 4表示一种类型。这意味着Number
类型的对象可以转换为short int
。
转换运算符没有明确声明的返回类型,也没有参数,因为返回类型正是签名中的type
。
这是一个转换函数,用于在各种条件下将您的类型转换为特定的其他类型,ISO C++11 12.3.2 Conversion functions
对此进行了介绍。
在您的情况下,当Number
实例需要转换为unsigned short
时会调用它。
通过提供转换运算符,您可以完全控制转换过程中发生的事情,包括以下邪恶行为:
#include <iostream>
struct X {
int val;
X(int v) { val = v; };
operator int() { return val + 1; }; // pure evil
friend std::ostream& operator<< (std::ostream&, X&);
};
std::ostream& operator<< (std::ostream &out, X &x) {
out << x.val;
return out;
}
int main (void) {
X xyzzy (42);;
std::cout << xyzzy << 'n';
std::cout << (int)xyzzy << 'n';
return 0;
}
当您直接使用实例时,它将输出值,但当您强制转换实例时,会输出完全不同的值。
当然,这是一个相当邪恶的用例,也不是一个真正好的用例,但当转换为整数时,您可以将其用于诸如舍入浮点而不是截断浮点之类的事情:
#include <iostream>
struct X {
double val;
X(double v) { val = v; };
operator int() { return (int)(val + 0.5); };
friend std::ostream& operator<< (std::ostream&, X&);
};
std::ostream& operator<< (std::ostream &out, X &x) {
out << x.val;
return out;
}
#define E 2.718281828456
int main (void) {
X xyzzy (E);
double plugh = E;
std::cout << plugh << " -> " << (int)plugh << 'n';
std::cout << xyzzy << " -> " << (int)xyzzy << 'n';
return 0;
}
该代码的输出为:
2.71828 -> 2
2.71828 -> 3
作为第一个答案的补充,当您使用关键字explicit
时,请注意区别,使用explicit
会迫使程序员断言他打算使用强制转换:
class Number {
private:
int num;
public:
explicit Number(int number) : num(number) {} // constructor
explicit operator unsigned short () const { // conversion operator
return num;
}
};
int main() {
Number classTypeNumber(10);
// unsigned short convertToUshortNumber = classTypeNumber; // error
// implicit conversion is not allowed.
// now you should explicit convert the instance first.
// typedef unsigned short int __u_short in types.h file.
unsigned short convertToUshortNumber = static_cast<__u_short>(classTypeNumber);
cout << convertToUshortNumber;
}