Оператор преобразования типов C ++ - PullRequest
5 голосов
/ 13 марта 2019

Я изучаю перегрузку операторов, есть некоторые части, которые трудно понять.

См. Пример кода.

class A {
    private:
    char a;
    int b;
    double c;

public:
A(char _a = 'a', int _b = 99, double _c = 1.618) :a(_a), b(_b), c(_c){
}

public:
    operator char() const {
        cout << "operator char() called" << endl;
        return this->a;
    }

operator int() const {
        cout << "operator int() called" << endl;
        return this->b;
    }

operator double() {
        cout << "operator double() called" << endl;
        return this->c;
    }
};
int main(void) {
    A a;
    char b = a;
    int c = a;
    double d = a;

    printf("%c\n", b);
    printf("%d\n", c);
    printf("%f\n", d);

    return 0;
}

Я создал этот код для проверки оператора преобразования типов и ожидал, что соответствующая функция будет вызываться для каждого типа данных.

Но результат ..

operator double() called
operator double() called
operator double() called
    <-- strange character is gone on board!
1
1.618000

Я не могу понять, почему результаты не таковы.

operator char() called
operator int() called
operator double() called
a
99
1.618

Почему двойной оператор вызывается при преобразовании в char и int?

Хорошего дня! :)

Ответы [ 2 ]

7 голосов
/ 13 марта 2019

Вы забыли const в операторе преобразования double:

operator double() const {  // <---------------------------
        cout << "operator double() called" << endl;
        return this->c;
    }
};

Как и в вашем примере a не равно const, двойное преобразование является наилучшим соответствием. Если вы исправите это, вы получите ожидаемый результат.

Живой пример

... некоторые основанные на мнении PS:

Я не нашел, что говорится в основных принципах об операторах преобразования, но если бы мне пришлось составить руководство для операторов преобразования, это было бы так: избегайте их. Если вы используете их, сделайте их explicit. Удивительные эффекты неявного преобразования значительно перевешивают выгоды.

В качестве примера рассмотрим std::bitset. Вместо предложения операторов конвертации он имеет to_string, to_ulong и to_ullong. Лучше, чтобы ваш код был явным. A a; double d = a; немного загадочно. Мне нужно взглянуть на определение класса, чтобы понять, что на самом деле происходит. С другой стороны, A a; double d = a.as_double(); может делать то же самое, но более выразительно.

1 голос
/ 13 марта 2019

Да, проблема в том, что вы сделали все операторы константными, кроме двойного. Я все еще немного удивлен, потому что это const просто означает, что вызов оператора не изменяет членов класса. Тем не менее, кажется, что для всех 3 вызывается только двойной оператор. Я бы сделал все 3 операции константными, и тогда он будет работать правильно.

Если у кого-то есть объяснение, почему это происходит, я также хотел бы знать. Приветствия.

operator char() const { // here is const
    cout << "operator char() called" << endl;
    return this->a;
}

operator int() const { // here is const
    cout << "operator int() called" << endl;
    return this->b;
}

operator double() { // here is no const
    cout << "operator double() called" << endl;
    return this->c;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...