Q1> У меня проблемы с пониманием следующего утверждения
template<class T> operator T*() const { return 0; }
Специально, что означает operator T*()
?
Это оператор неявного преобразования. Это позволяет иметь объекты типа, к которому он относится, неявным образом конвертировать в целевой тип T*
здесь. Эта версия является специальной, поскольку, будучи шаблоном, она может конвертировать объект этого NullClass
в любой тип указателя.
Неявное преобразование осуждается по уважительным причинам. У них плохая привычка вставлять в неожиданные моменты, заставляя компилятор вызывать непреднамеренную версию перегруженной функции. Наличие шаблонного оператора неявного преобразования особенно вредно, потому что шаблонизация увеличивает возможности.
Q2> Почему f (NULL) наконец вызывает f (строку *)?
см. Выше. Преобразование в int
невозможно, поэтому оператор неявного преобразования запускает и преобразует объект NullClass
в любой запрошенный указатель.
Я предполагаю, что это предназначено. Обычно вы не хотите, чтобы указатель был преобразован в целое число, поэтому этот класс имеет неявное преобразование в любой указатель, но не в int
.
То, что NullClass
не так уж и плохо, но NULL
его пример - чистая глупость. Как только вы включите любой из множества заголовков, которые определяют макрос NULL
(определенный как 0
, то есть целочисленная константа), препроцессор будет растоптывать весь источник и заменять каждое использование NULL
на 0
, Поскольку вы не можете избежать этого, эта ошибка делает весь класс практически бесполезным.