奇怪的c++运算符(运算符unsigned short())



我遇到了一个奇怪的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;
}

最新更新