简体   繁体   English

用户定义的C ++转换

[英]User Defined Conversions in C++

Recently, I was browsing through my copy of the C++ Pocket Reference from O'Reilly Media, and I was surprised when I came across a brief section and example regarding user-defined conversion for user-defined types: 最近,我浏览 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;
}

I've been programming in C++ for awhile, and this is the first time I've ever seen this sort of operator overloading. 我用C ++编程了一段时间,这是我第一次看到这种运算符重载。 The book's description of this subject is somewhat brief, leaving me with a few unanswered questions about this feature: 这本书对这个主题的描述有些简短,给我留下了一些关于这个功能的未解答的问题:

  • Is this a particularly obscure feature? 这是一个特别模糊的功能吗? As I said, I've been programming in C++ for awhile and this is the first time I've ever come across this. 正如我所说,我已经用C ++编程了一段时间,这是我第一次遇到这个问题。 I haven't had much luck finding more in-depth material regarding this. 我没有太多运气找到更深入的材料。
  • Is this relatively portable? 这相对便携吗? (I'm compiling on GCC 4.1) (我正在编写GCC 4.1)
  • Can user-defined conversions to user defined types be done? 是否可以完成用户定义的用户定义转换? eg 例如

    operator std::string () { /* code */ } operator std :: string(){/ * code * /}

Is this a particularly obscure feature? 这是一个特别模糊的功能吗?

Yes, conversion operators aren't used very often. 是的,不经常使用转换运算符。 The places I've seen them are for user-defined types that can degrade to built-in ones. 我见过它们的地方是用户定义的类型,可以降级为内置类型。 Things like a fixed-precision number class that supports converting to/from atomic number types. 像固定精度数字类,支持转换为原子数类型/从原子数类型转换。

Is this relatively portable? 这相对便携吗?

As far as I know, it is. 据我所知,确实如此。 They've been in the standard forever. 他们永远都是标准。

Can user-defined conversions to user defined types be done? 是否可以完成用户定义的用户定义转换?

Yes, that's one of the features of constructors. 是的,这是构造函数的特性之一。 A constructor that takes a single argument effectively creates a conversion operator from the argument type to your class's type. 采用单个参数的构造函数有效地创建了从参数类型到类类型的转换运算符。 For example, a class like this: 例如,像这样的类:

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

Let's you do: 我们你做的:

Foo f = 123;

If you've used std::string before, odds are you've used this feature without realizing it. 如果你之前使用过std::string ,那么你很可能没有意识到这个功能。 (As an aside, if you want to prevent this behavior, declare any single-argument constructors using explicit .) (顺便说一句,如果要防止此行为,请使用explicit声明任何单参数构造explicit 。)

It's not particularly obscure; 它并不是特别模糊; it is very portable (it is part of the language after all), and conversion to user-defined types is possible. 它非常便携(毕竟它是语言的一部分),并且可以转换为用户定义的类型。

One word of caution, having a lot of possible implicit conversion paths can lead to unexpected conversion being invoked and surprising bugs. 需要注意的是,有很多可能的隐式转换路径会导致调用意外转换和令人惊讶的错误。 Also, having non-explicit converting constructors and conversion functions between several user-defined types can lead to more ambigious conversion sequeunces which can be a pain to resolve. 此外,在几个用户定义的类型之间使用非显式转换构造函数和转换函数可能会导致更加暧昧的转换序列,这可能是一个难以解决的问题。

It was about one of the first things I stumbled across when I was learning C++, so I'd say that no, it is not all that obscure. 这是我在学习C ++时遇到的第一件事,所以我会说不,不是那么模糊。

One thing I would caution on though: Use the explicit keyword with them unless you know exactly what you are doing. 但有一点我要注意:除非你确切知道自己在做什么,否则请使用explicit关键字。 Implicit conversions can cause code to behave in unexpected ways, so you should avoid using them in most cases. 隐式转换可能导致代码以意外方式运行,因此在大多数情况下应避免使用它们。 Frankly, I'd be happier if the language didn't have them. 坦率地说,如果语言没有它,我会更开心。

这是一个特别有用的标准C ++特性,并没有一点模糊:)你可以使用基本和用户定义类型的转换运算符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM