Определяемые пользователем преобразования в C++

Недавно, я просматривал свою копию Ссылки Кармана C++ от O'Reilly Media, и я был удивлен, когда я столкнулся с кратким разделом и примером относительно пользовательского преобразования для пользовательских типов:

#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),
  • Могут пользовательские преобразования в определяемые пользователем типы быть сделанными? например.

    станд. оператора:: строка () {/* кодирует */}

9
задан wash 9 June 2010 в 18:25
поделиться

4 ответа

Это особенно непонятная функция?

Да, операторы преобразования используются не очень часто. Я встречал их только для пользовательских типов, которые могут вырождаться до встроенных. Например, класс чисел фиксированной точности, который поддерживает преобразование в/из атомарных типов чисел.

Это относительно переносимо?

Насколько я знаю, да. Они были в стандарте всегда.

Можно ли выполнять преобразования к типам, определенным пользователем?

Да, это одна из особенностей конструкторов. Конструктор, принимающий один аргумент, фактически создает оператор преобразования от типа аргумента к типу вашего класса. Например, класс типа this:

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

Позволяет вам делать:

Foo f = 123;

Если вы уже использовали std::string, то, скорее всего, вы использовали эту возможность, не осознавая этого. (В качестве примера, если вы хотите предотвратить такое поведение, объявляйте любые одноаргументные конструкторы с помощью explicit.)

.
12
ответ дан 4 December 2019 в 09:12
поделиться

Это было примерно одно из первых, на что я наткнулся, когда изучал C ++, поэтому я бы сказал, что нет, это не так уж и непонятно.

Однако я хотел бы предупредить об одном: используйте с ними ключевое слово explicit , если вы точно не знаете, что делаете. Неявные преобразования могут привести к неожиданному поведению кода, поэтому в большинстве случаев их следует избегать. Честно говоря, я был бы счастлив, если бы их не было в языке.

4
ответ дан 4 December 2019 в 09:12
поделиться

Это не особенно непонятно; это очень переносимо (в конце концов, это часть языка), и возможно преобразование в пользовательские типы.

Одно слово предостережения: наличие большого количества возможных неявных путей преобразования может привести к неожиданному вызову преобразования и неожиданным ошибкам. Кроме того, наличие неявных конструкторов преобразования и функций преобразования между несколькими определяемыми пользователем типами может привести к более неоднозначным ситуациям преобразования, которые будет очень сложно разрешить.

4
ответ дан 4 December 2019 в 09:12
поделиться

Это особенно полезная стандартная функция C++ и не такая уж и непонятная :) Вы можете использовать для операторов преобразования как фундаментальные, так и определяемые пользователем типы.

3
ответ дан 4 December 2019 в 09:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: