Модераторы: Poseidon

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы с перегрузкой обератора << в С++, при использовании шаблонов 
:(
    Опции темы
Pakshin A. S.
Дата 20.5.2006, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 5
Всего: 61



Учебная прога:
Код

#include "stdafx.h"
#include <iostream>

using namespace std;

template <class X>
    class CComplex
    {
    private:
        X Re;
        X Im;

        X _abs(X temp)
        {
            if (temp < 0)
                return -temp;
            else
                return temp;
        }
    public:
        CComplex operator+= (const CComplex& obj)
        {
            CComplex temp;

            temp.Im = Im + obj.Im;
            temp.Re = Re + obj.Re;

            return temp;
        }
        CComplex operator+ (const CComplex& obj)
        {
            CComplex temp;

            temp.Im = Im;
            temp.Re = Re;

            temp += obj;

            return temp;
        }
        CComplex operator-= (const CComplex& obj)
        {
            CComplex temp;

            temp.Im = Im - obj.Im;
            temp.Re = Re - obj.Re;

            return temp;
        }
        CComplex operator- (const CComplex& obj)
        {
            CComplex temp;

            temp.Im = Im;
            temp.Re = Re;

            temp -= obj;

            return temp;
        }
        CComplex operator= (const CComplex &obj)
        {
            Re = obj.Re;
            Im = obj.Im;
        }

        friend ostream& operator<< (ostream& stream, CComplex &obj);
        friend CComplex SetData (X _Re, X _Im);
    };

template <class X>
    CComplex <X> SetData (X _Re, X _Im)
    {
        CComplex <X> temp;
    
        temp.Re = _Re;
        temp.Im = _Im;

        return temp;
    }

template <class X>
    ostream& operator<< (ostream& stream, CComplex /*<X>*/ &obj)
    {
        int flag = 0;
        
        if (obj.Re != 0)
        {
            stream << obj.Re;
            flag = 1;
        }
    
        if (obj.Im == 0)
        {
            if (flag == 0)
                stream << "0";
        }
        else
        {
            if (obj.Im < 0)
                stream << "-";
            else
                if (flag == 1)
                    stream << "+";
            stream << obj._abs(obj.Im) << "i";
        }
    }

int main(int argc, char* argv[])
{
    CComplex <int> C1;
    CComplex <int> C2;
    
    C1 = SetData(1, 2);
    C2 = SetData(2, 3);

    cout << C1 << endl << C2;

    cout << C1 + C2;

    cout << C1 - C2;
    
    return 0;
}


Ошибки:
Цитата(Microsoft Visual C++ 6.0)

error C2955: 'CComplex' : use of class template requires template argument list - на строке с перегрузкой оператора вне класса
 
PM   Вверх
DeadSoul
Дата 20.5.2006, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: нет
Всего: 11



Код

ostream& operator<< (ostream& stream, const CComplex<X> &obj)
 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
MAKCim
Дата 20.5.2006, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Код

template<class X> class CComplex;  // Объявление чтобы работал код ниже

template<class X> ostream& 
    operator<<(ostream&, CComplex<X>&);

template<class C> class CComplex
{
...
    friend ostream& operator<< <>(ostream&,CComplex<X>&);
...
};

template<class X> ostream& 
    operator<<(ostream& stream, CComplex<X>& obj)
{
...
}
  

Это сообщение отредактировал(а) MAKCim - 20.5.2006, 13:02


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Pakshin A. S.
Дата 20.5.2006, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 5
Всего: 61



Не компилицца...

Код

// Project5.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>

using namespace std;

template <class X> class CComplex;

template <class X> ostream& operator<<(ostream&, CComplex<X>&);

template <class C>
    class CComplex
    {
    private:
        C Re;
        C Im;

        C _abs(C temp)
        {
            if (temp < 0)
                return -temp;
            else
                return temp;
        }
    public:
        CComplex operator+= (const CComplex& obj)
        {
            CComplex temp;

            temp.Im = Im + obj.Im;
            temp.Re = Re + obj.Re;

            return temp;
        }
        CComplex operator+ (const CComplex& obj)
        {
            CComplex temp;

            temp.Im = Im;
            temp.Re = Re;

            temp += obj;

            return temp;
        }
        CComplex operator-= (const CComplex& obj)
        {
            CComplex temp;

            temp.Im = Im - obj.Im;
            temp.Re = Re - obj.Re;

            return temp;
        }
        CComplex operator- (const CComplex& obj)
        {
            CComplex temp;

            temp.Im = Im;
            temp.Re = Re;

            temp -= obj;

            return temp;
        }
        CComplex operator= (const CComplex &obj)
        {
            Re = obj.Re;
            Im = obj.Im;
        }

        friend ostream& operator<< (ostream& stream, CComplex <C> &obj);
        friend CComplex SetData (C _Re, C _Im);
    };

template <class X>
    CComplex <X> SetData (X _Re, X _Im)
    {
        CComplex <X> temp;
    
        temp.Re = _Re;
        temp.Im = _Im;

        return temp;
    }

template <class X>
    ostream& operator<< (ostream& stream, CComplex <X> &obj)
    {
        int flag = 0;
        
        if (obj.Re != 0)
        {
            stream << obj.Re;
            flag = 1;
        }
    
        if (obj.Im == 0)
        {
            if (flag == 0)
                stream << "0";
        }
        else
        {
            if (obj.Im < 0)
                stream << "-";
            else
                if (flag == 1)
                    stream << "+";
            stream << obj._abs(obj.Im) << "i";
        }
    }

int main(int argc, char* argv[])
{
    CComplex <int> C1;
    CComplex <int> C2;
    
    C1 = SetData(1, 2);
    C2 = SetData(2, 3);

    cout << C1 << endl << C2;

    cout << C1 + C2;

    cout << C1 - C2;
    
    return 0;
}
 
PM   Вверх
DeadSoul
Дата 20.5.2006, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: нет
Всего: 11



Pakshin A. S., в какой строчке, какое сообщение об ошибке? 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Pakshin A. S.
Дата 20.5.2006, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 5
Всего: 61



error C2248: 'Re' : cannot access private member declared in class 'CComplex<int>'

на 94'ой 
PM   Вверх
Damarus
Дата 20.5.2006, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 671
Регистрация: 6.5.2006

Репутация: 7
Всего: 29



Код

#include <iostream>    

using namespace std;    

template <class X> class CComplex;
template <class X> CComplex <X> SetData (X _Re, X _Im);
template <class X> ostream& operator<< (ostream& stream, CComplex <X> &obj);

template <class X> class CComplex    
{
private:    
   X Re;    
   X Im;    
   X _abs(X temp)    
   {    
      if (temp < 0)    
         return -temp;    
      else    
         return temp;    
   }

public:    
   CComplex& operator+= (const CComplex& obj)    
   {    
      Im += obj.Im;    
      Re += obj.Re;    
      return *this;    
   }    
   CComplex operator+ (const CComplex& obj)    
   {    
      CComplex temp = *this;
      temp += obj;    
      return temp;    
   }
   CComplex& operator-= (const CComplex& obj)    
   {        
      Im -= obj.Im;    
      Re -= obj.Re;    
      return *this;    
   }    
   CComplex operator- (const CComplex& obj)    
   {    
      CComplex temp = *this;
      temp -= obj;    
      return temp;    
   }    
   CComplex& operator= (const CComplex &obj)    
   {    
      Re = obj.Re;    
      Im = obj.Im;
      return *this;
   }

private:
   template<class X> friend ostream& operator << (ostream&, CComplex<X>&);
   template <class X> friend CComplex<X> SetData (X _Re, X _Im);
};

template <class X>    
CComplex <X> SetData (X _Re, X _Im)    
{    
   CComplex <X> temp;    

   temp.Re = _Re;    
   temp.Im = _Im;    
   return temp;    
}

template <class X>
ostream& operator<< (ostream& stream, CComplex <X> &obj)    
{    
   int flag = 0;    

   if (obj.Re != 0)    
   {    
      stream << obj.Re;    
      flag = 1;    
   }    

   if (obj.Im == 0)    
   {    
      if (flag == 0)    
         stream << "0";    
   }    
   else    
   {    
      if (obj.Im < 0)    
         stream << "-";    
      else    
         if (flag == 1)    
            stream << "+";
      stream << obj._abs(obj.Im) << "i";    
   }

   return stream;
}

int main(int argc, char* argv[])    
{    
   CComplex <int> C1;    
   CComplex <int> C2;    

   C1 = SetData(1, 2);    
   C2 = SetData(2, 3);    
   cout << C1 << endl << C2 << endl;    
   cout << C1 + C2 << endl;    
   cout << C1 - C2 << endl;

   return 0;    
}
 
PM MAIL ICQ Jabber   Вверх
Pakshin A. S.
Дата 20.5.2006, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 5
Всего: 61



Damarus, 

error C2563: mismatch in formal parameter list
на 
cout << C1 << endl << C2; 
PM   Вверх
MAKCim
Дата 20.5.2006, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Pakshin A. S.
Цитата

...
        friend ostream& operator<< <>(ostream& stream, CComplex <C> &obj);
        friend CComplex SetData (C _Re, C _Im);
...

смотрите мой пост выше
Добавлено @ 17:25 
Цитата

error C2248: 'Re' : cannot access private member declared in class 'CComplex<int>'

ошибка потому что без <> operator<< просто сторонняя функция, не имеющая доступа к реализации CComplex  

Это сообщение отредактировал(а) MAKCim - 20.5.2006, 17:26


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Damarus
Дата 20.5.2006, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 671
Регистрация: 6.5.2006

Репутация: 7
Всего: 29



Pakshin A. S., не знаю, у меня всё работает: 

Это сообщение отредактировал(а) Damarus - 20.5.2006, 17:53

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  Build.gif 40,87 Kb
PM MAIL ICQ Jabber   Вверх
Pakshin A. S.
Дата 20.5.2006, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 5
Всего: 61



MAKCim, поставлены <>... Ругается на эту строчку: error C2143: syntax error : missing ';' before '<'

Код

        friend ostream& operator<< <>(ostream& stream, CComplex <C> &obj);
        friend CComplex SetData (C _Re, C _Im);
    };




Damarus, я не спорю, но у меня Microsoft Visual C++ 6.0, а на картинке вроде не тот компилятор, что у меня... smile 
PM   Вверх
MAKCim
Дата 20.5.2006, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата

Ругается на эту строчку: error C2143: syntax error : missing ';' before '<'

не знаю, может проблема в VS6.0
у меня все OK, проверял (g++ 4.0.2)

сделайте public методы SetRe, SetIm, GetRe, GetIm
и шаблон оператора operator<< (не используя friend), вместо obj.Re пишите obj.GetRe() и т д
 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Damarus
Дата 20.5.2006, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 671
Регистрация: 6.5.2006

Репутация: 7
Всего: 29



Pakshin A. S., как я делал:
1. Скопировал твой код (9-ю постами выше). Попытался скомпилировать. Получил:
Цитата

error C4716: 'CComplex<int>::operator=' : must return a value


2. Добавил 
Код
return *this;
 в CComplex<int>::operator=. Попытался скомпилировать. Получил:
Цитата

error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class CComplex<int> &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$CComplex@H@@@Z) referenced in function _main    Test.obj    

и
Цитата

error LNK2019: unresolved external symbol "class CComplex<int> __cdecl SetData(int,int)" (?SetData@@YA?AV?$CComplex@H@@HH@Z) referenced in function _main    Test.obj    


3. Посмотрел MSDN по вопросу LNK2019. Там есть подходящий пример:
Цитата

The following sample generates LNK2019 on a user-defined operator.
Код

// LNK2019e.cpp
// compile with: /EHsc
// LNK2019 expected
#include <iostream>
using namespace std;

template<class T> class 
Test {
   friend ostream& operator<<(ostream&, Test&);
   // Uncomment the following line to resolve.
   // template<typename T> friend ostream& operator << (ostream&, Test<T>&);
};

template<typename T>
ostream& operator<<(ostream& os, Test<T>& tt) {
   return os;
}

int main() {
   Test<int> t;
   cout << "Test: " << t << endl;   // unresolved external
}



4. На основе этого примера добавил:
Код

template<class C> friend ostream& operator<< (ostream& stream, CComplex <C> &obj);    
template<class C> friend CComplex<C> SetData (C _Re, C _Im);

Попытался скомпилировать. Получил:
Цитата

error C4716: 'operator<<<int>' : must return a value


5. Добавил 
Код
return stream;
.

После этого программа нормально скомпилировалась, но выдавала неверные результаты (вроде). Изменил операции в классе CComplex (см. выше).  

Это сообщение отредактировал(а) Damarus - 20.5.2006, 18:37
PM MAIL ICQ Jabber   Вверх
Pakshin A. S.
Дата 20.5.2006, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 5
Всего: 61



Цитата(MAKCim @  20.5.2006,  19:17 Найти цитируемый пост)
сделайте public методы SetRe, SetIm, GetRe, GetIm

Задача - использование именно дружественности.


Damarus, Спасибо за подробный ответ. Но вот только пытаюсь пихать в разные места.. что-то пока не нашел комбинации верной... smile МОжет проще будет выложить код? Я бы его сравнил с тем, что у меня и бытрее нашел ошибки у себя...

Добавлено @ 19:52 
Говорил именно про проблемы с перегрузкой, а не с забытием возврата значения функциями...

Добавлено @ 19:57 
Цитата(MAKCim @  20.5.2006,  19:17 Найти цитируемый пост)
сделайте public методы SetRe, SetIm, GetRe, GetIm


Так-то работат.. smile

Сделал public все... smile а вот на private все так же ругается, что не может получить доступ. 
PM   Вверх
Damarus
Дата 20.5.2006, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 671
Регистрация: 6.5.2006

Репутация: 7
Всего: 29



Pakshin A. S., вот немного изменённый твой код (все отличия прокоментированы):
Код

#include <iostream>

using namespace std;

template <class C> class CComplex
{    
private:
   C Re;
   C Im;
   C _abs(C temp)
   {    
      if (temp < 0)
         return -temp;
      else
         return temp;
   }

public:
   CComplex operator+= (const CComplex& obj)
   {
      CComplex temp;
      temp.Im = Im + obj.Im;
      temp.Re = Re + obj.Re;
      return temp;
   }

   CComplex operator+ (const CComplex& obj)
   {
      CComplex temp;
      temp.Im = Im;
      temp.Re = Re;
      temp += obj;
      return temp;
   }

   CComplex operator-= (const CComplex& obj)
   {
      CComplex temp;
      temp.Im = Im - obj.Im;
      temp.Re = Re - obj.Re;
      return temp;
   }

   CComplex operator- (const CComplex& obj)
   {
      CComplex temp;
      temp.Im = Im;
      temp.Re = Re;
      temp -= obj;
      return temp;
   }

   CComplex operator= (const CComplex &obj)
   {
      Re = obj.Re;
      Im = obj.Im;

      return *this; // Добавленно для нормальной компиляции.
   }

   // Перед friend ostream& operator<< (ostream& stream, CComplex<C>& obj);
   // добавленно template<class C>, параметор obj изменён с CComplex&
   // на CComplex<C>&
   template<class C> friend ostream& operator<< (ostream& stream, CComplex<C>& obj);

   // Перед friend CComplex SetData (C _Re, C _Im);
   // добавленно template<class C>, после friend CComplex
   // добавленно <C>
   template<class C> friend CComplex<C> SetData (C _Re, C _Im);
};

template <class X> CComplex <X> SetData(X _Re, X _Im)
{
   CComplex <X> temp;

   temp.Re = _Re;
   temp.Im = _Im;
   return temp;
}    

template <class X> ostream& operator<< (ostream& stream, CComplex<X>& obj)
{
   int flag = 0;

   if (obj.Re != 0)
   {
      stream << obj.Re;
      flag = 1;
   }

   if (obj.Im == 0)
   {
      if (flag == 0)
         stream << "0";
   }
   else
   {
      if (obj.Im < 0)
         stream << "-";
      else
         if (flag == 1)
            stream << "+";
      stream << obj._abs(obj.Im) << "i";
   }

   return stream; // Добавленно для нормальной компиляции.
}

int main(int argc, char* argv[])
{
   CComplex <int> C1;
   CComplex <int> C2;

   C1 = SetData(1, 2);
   C2 = SetData(2, 3);
   cout << C1 << endl << C2;
   cout << C1 + C2;
   cout << C1 - C2;

   return 0;    
}
 
PM MAIL ICQ Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0616 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.