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

时间:2014-09-01 02:59:56

标签: c++ operator-overloading

我遇到了一个奇怪的c ++运算符。

http://www.terralib.org/html/v410/classoracle_1_1occi_1_1_number.html#a0f2780081f0097af7530fe57a100b00d

class Number {
.. 
    operator unsigned short () const;



};

我将此运营商称为: 一个号码(..); unsigned short b = a.operator unsigned short();

这有效,但我无法理解它是如何运作的。

首先,该运营商没有返回值。 秒,a.operator unsigned short()对我来说真的很奇怪。什么是更好的方式来称呼它?

如果我打电话: unsigned short b = a;操作员会被叫到吗?有什么c ++标准可以说这个吗?

4 个答案:

答案 0 :(得分:5)

该功能是用户定义的转换运算符。有关详细信息,请访问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 :: operator int()转换。 - 结束示例]

答案 1 :(得分:1)

这是转换运算符。转换函数通常具有通用形式

operator type() const;

其中type代表一种类型。这意味着Number类型的对象可以转换为short int

转换运算符没有明确声明的返回类型且没有参数,因为返回类型恰好是签名中的type

答案 2 :(得分:0)

这是一个转换函数,被称为在各种条件下将您的类型转换为特定的其他类型,并且在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

答案 3 :(得分:0)

作为第一个答案的补充,当您使用关键字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;
}