Определенные пользователем преобразования в C ++ - PullRequest
9 голосов
/ 09 июня 2010

Недавно я просматривал свою копию C ++ Pocket Reference от 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)
  • Можно ли выполнить пользовательские преобразования в пользовательские типы? например,

    оператор std :: string () {/ * code * /}

Ответы [ 4 ]

12 голосов
/ 09 июня 2010

Это особенно неясная особенность?

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

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

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

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

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

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

Давайте сделаем:

Foo f = 123;

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

4 голосов
/ 09 июня 2010

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

4 голосов
/ 09 июня 2010

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

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

3 голосов
/ 09 июня 2010

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

...