12

最近,我浏览了O'Reilly Media的 C++ Pocket Reference副本,当我看到一个关于用户定义类型的用户定义转换的简短部分和示例时,我感到很惊讶:

#include <iostream>

class account {

    private:
        double balance;

    public:
        account (double b) { balance = b; }

        operator double (void) { return balance; }
};

int main (void) {

    account acc(100.0);
    double balance = acc;

    std::cout << balance << std::endl;

    return 0;
}

我已经用 C++ 编程了一段时间,这是我第一次看到这种运算符重载。这本书对这个主题的描述有点简短,给我留下了一些关于这个特性的未回答的问题:

  • 这是一个特别晦涩的功能吗?正如我所说,我已经用 C++ 编程了一段时间,这是我第一次遇到这种情况。我没有太多运气找到有关此的更深入的材料。
  • 这个比较便携吗?(我在 GCC 4.1 上编译)
  • 可以将用户定义的类型转换为用户定义的类型吗?例如

    运算符 std::string () { /* 代码 */ }

4

4 回答 4

15

这是一个特别晦涩的功能吗?

是的,转换运算符不经常使用。我见过它们的地方是用户定义的类型,这些类型可以降级为内置类型。诸如支持与原子序数类型转换的固定精度数字类之类的东西。

这个比较便携吗?

据我所知,确实如此。他们一直在标准中。

可以将用户定义的类型转换为用户定义的类型吗?

是的,这是构造函数的特性之一。采用单个参数的构造函数有效地创建了从参数类型到类类型的转换运算符。例如,像这样的一个类:

class Foo {
public:
    Foo(int n) {
        // do stuff...
    }
}

让你做:

Foo f = 123;

如果您以前使用std::string过,那么您很可能在没有意识到的情况下使用过此功能。(顺便说一句,如果您想阻止这种行为,请使用 . 声明任何单参数构造函数explicit。)

于 2010-06-09T18:30:40.100 回答
5

它不是特别晦涩。它非常便携(毕竟它是语言的一部分),并且可以转换为用户定义的类型。

需要注意的是,有很多可能的隐式转换路径可能会导致调用意外转换和令人惊讶的错误。此外,在几个用户定义的类型之间具有非显式转换构造函数和转换函数可能会导致更模棱两可的转换序列,这可能是一个难以解决的问题。

于 2010-06-09T18:30:28.370 回答
4

这是我在学习 C++ 时偶然发现的第一件事,所以我想说不,它并不是那么晦涩难懂。

不过我会提醒一件事:explicit除非您确切知道自己在做什么,否则请对他们使用关键字。隐式转换会导致代码以意想不到的方式运行,因此在大多数情况下应避免使用它们。坦率地说,如果语言没有它们,我会更高兴。

于 2010-06-09T18:32:38.193 回答
3

这是一个特别有用的标准 C++ 功能,而且并不晦涩:) 您可以将基本类型和用户定义类型都用于转换运算符。

于 2010-06-09T18:30:31.697 回答