Перегрузка оператора "оператор T * ()" производит оператор сравнения? - PullRequest
4 голосов
/ 09 ноября 2010
class Test
{
public:
    operator Test * () { return NULL; };
};

int main()
{
    Test test;
    if (test == NULL)
        printf("Wtf happened here?\n");

    return 0;
}

Как получается, что этот код компилируется?Как Test получил оператор сравнения?Есть ли какая-то неявная кастинг?Что этот перегруженный оператор вообще означает (и делает)?

Ответы [ 4 ]

7 голосов
/ 09 ноября 2010

Перегруженный оператор добавляет преобразование из Test в Test *.Поскольку не определен ни один оператор сравнения, который принимает Test и NULL в качестве аргументов, пробуются любые существующие операторы преобразования.operator Test * возвращает тип, сравнимый с NULL, поэтому он используется.

1 голос
/ 09 ноября 2010

Да, вы добавили неявное преобразование в T*, поэтому компилятор будет использовать его для сравнения с NULL.

Несколько других замечаний:

NULLявляется сокращением для 0, так что это означает, что сравнение с 0 будет разрешено.(Однако это не так для других целочисленных значений. 0 - особенное.)

Ваш тип также может быть неявно использован в логических контекстах.То есть это допустимо:

Test test;
if (test)
{
    // ...
}

C ++ 0x позволяет вам указать ключевое слово explicit , чтобы операторы преобразования могли запретить подобные вещи.

Неявное преобразование в типы указателей часто довольно сомнительно.В дополнение к подводным камням преобразования, возникающим в неожиданных случаях, он может разрешать опасные ситуации, если объекту принадлежит возвращаемый указатель.Например, рассмотрим строковый класс, который допускает неявное преобразование в const char*:

BadString ReturnAString();

int main()
{
    const char* s = ReturnAString();
    // Uh-oh.  s is now pointing to freed memory.

    // ...
}
0 голосов
/ 09 ноября 2010

+ 1 за ответ Баффе. Если вы хотите каким-то образом представить какой-либо экземпляр обернутого объекта с помощью *, возможно, вам следует перегрузить -> вместо перегрузки *.

class Bar
{
public:
   void Baz() { ... }
}

class Foo
{
private:
    Bar* _bar;
public:
    Bar* operator -> () { return _bar; }
}

// call like this:
Foo f;
f->Baz();

Просто мысль.

0 голосов
/ 09 ноября 2010

Вы не определили свое собственное сравнение, поэтому компилятор сделал его для вас. однако вы пытались перегрузить оператор разыменования ... чего я не понимаю, почему.

вы хотите определить свой оператор == функцию

читать это

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...