Перегрузка оператора вставки C (<<)

#c #pointers #reference #operator-overloading #overload-resolution

#c #указатели #ссылка #перегрузка оператора #перегрузка-разрешение

Вопрос:

Я работаю над назначением, в котором я должен перегрузить оператор вставки, чтобы получить объект Node. Я создал функцию перегрузки оператора вне определения класса, но внутри файла node.h. Все компилируется нормально, но перегруженный оператор не вызывается, вместо этого я получаю простой адрес объекта.

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

Мой код в его нынешнем виде прямо сейчас:

 /** OPERATOR << ***********************************/
template<class T>
inline std::ostream amp; operator << (std::ostream amp; out, const Node <T> *amp; pHead)
{
    out << "INCOMPLETE";
    return out;
}
  

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

Вызывающий код:

 // create
Node <char> * n = NULL;

// code modifying n

// display
cout << "t{ " << n << " }n";
  

Комментарии:

1. cout << *n; было бы более простым решением

2. Это верно, но, как указано, я не могу изменить вызывающий код.

3. извините, пропустил эту часть.

4. не очень уверен, возможно, удаление amp; в const Node <T> *amp; сработает, или вы также можете предоставить неконстантную версию.

Ответ №1:

Обратите внимание, что тип параметра pHead является ссылкой на неконстантный, const Node<T>* является неконстантным указателем на const, тип аргумента n является Node<T>* (т. е. неконстантным указателем на неконстантный). Их тип не совпадает, Node<T>* необходимо преобразовать в const Node<T>* , который является временным и не может быть привязан к ссылке на неконстантный.

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

Но ссылка на const может быть привязана к temporary, поэтому вы можете изменить тип параметра на ссылку на const:

 template<class T>
inline std::ostream amp; operator << (std::ostream amp; out, const Node <T> * const amp; pHead)
//                                                                      ~~~~~
  

Или измените его на передаваемый по значению, Node<T>* будет неявно преобразован в const Node<T>* при передаче в качестве аргумента. (Передача указателя по ссылке на const не имеет особого смысла.)

 template<class T>
inline std::ostream amp; operator << (std::ostream amp; out, const Node <T> * pHead)
  

Наконец, перегрузка operator<< типом указателя выглядит странно. Наиболее распространенной формой с пользовательским типом будет:

 template<class T>
std::ostream amp; operator << (std::ostream amp; out, const Node <T> amp; pHead)
  

Комментарии:

1. Благодарим вас за разъяснение деталей использования const и ссылочных типов. Я начал с последнего блока кода, но модератор класса сообщил мне, что ему необходимо принять указатель. Первый опубликованный вами блок кода отлично работает (во всяком случае, для этого назначения.) Я буду помнить о ваших рекомендациях в дальнейшем.

Ответ №2:

Проблема в том, что средство вставки принимает параметр типа const Node<T>* , но он вызывается с аргументом типа Node<T>* ; преобразование из T* в const T* не выполняется. Итак, «исправление» заключается в удалении const из средства вставки потока.

Но, как намекнуто в комментарии, наличие средства вставки, которое принимает указатель на тип, является плохой идеей. Это должно занять const Node<T>amp; , как и у всех других вставщиков в мире. Я понимаю, что это ограничение, налагаемое присваиванием; если это так, то это идиотизм. Тебя плохо учат.

Комментарии:

1. Вы правы в том, что это ограничение класса. В курсе мы создаем класс Node и некоторые независимые функции. На следующей неделе мы берем класс Node и эти функции и объединяем их в класс с двойной связью List. До сих пор (5 недель) все другие структуры данных использовали указанный вами общий метод. Я полагаю, что на этой неделе все по-другому, потому что класс Node не является полным абстрактным типом данных.