ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Программирование > С/С++, C#, Delphi, .NET, Asm
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

Жёсткая задачка про ООП в С++
  #1  
Старый 14.06.2007, 00:16
Аватар для pch
pch
Познающий
Регистрация: 22.10.2005
Сообщений: 37
Провел на форуме:
520745

Репутация: 141
По умолчанию Жёсткая задачка про ООП в С++

Прелюдия (можно смело пропустить)
Вообщем хочется написать класс полиномов над некоторым типом aType так, чтобы операции были понолстью френд-перегружены, т.е. чтобы работало int==Polynom<int>, int*Polynom<int> и другие приятности.
В не-шаблонном случае это - тривиальнейшая задача. Как только я ввожу шаблоны, aType престаёт приводиться к Polynom, хотя конструктор Polynon<int> имеется. Если выкинуть контекст, и оставить только саму проблему, то получится

Задача
Заставить работать парой волшебных пассов
Код:
#include <iostream>
using namespace std;

template <class aType>
class testClass{
public:
       aType data;
       testClass(aType c): data(c) {}
       bool friend operator==<aType>(testClass<aType>, testClass<aType>);
};
template <class aType>
bool operator==(testClass<aType> a, testClass<aType> b){
       return a.data==b.data;
}
int main(){
       int a=4;
       testClass<int> b(4);
       if (a==b) cout << "a equals b\n";
       if (b==a) cout << "b equals a\n";
}
В таком состоянии выдает две ошибки:
Код:
no match for `testClass<int> & == int &`
no match for `int & == testClass<int> &`
Если вызывать явные конструкторы Polynom(a)==b, всё работает, но тогда инкапсуляция и всё изящество идёт лесом.

Действительно хоть какое-то решение - делать приведения явно, но внутри класса. Т.е. добавив
Код:
      
bool friend operator==<aType>(aType a, testClass b<aType>);
bool friend operator==<aType>(testClass a<aType>, aType b);
Ни в одной книге попавшейся мне, включая Строуструпа, этого нет. Но кажется совсем сомнительным, что это невозможно, это ж С++!!! Вообщем, надеюсь прояснить этот вопрос
 
Ответить с цитированием

  #2  
Старый 14.06.2007, 00:59
Аватар для _Great_
_Great_
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме:
5339610

Репутация: 4360


Отправить сообщение для _Great_ с помощью ICQ
По умолчанию

Ну ясен пень, ты сравниваешь целое число и объект класса. У тебя же нет оператора их сравнения. Кстати, что за компилер? Обычно такое компилеры кушают, создавая временные объекты.. хотя хз, я точно не знаю
 
Ответить с цитированием

  #3  
Старый 14.06.2007, 11:26
Аватар для Aag
Aag
Познающий
Регистрация: 26.07.2005
Сообщений: 54
Провел на форуме:
47901

Репутация: 46
По умолчанию

По-моему, просто надо реализовать соответствующий оператор копирования, поскольку по умолчанию генерируется такой оператор копирования
Код:
testClass<aType>& testClass<aType>::operator = (const testClass<aType>& hs)
вам для неявного преобразования надо реализовать такой оператор класса, который в качестве аргумента принимает не testClass<aType>& , а аргумент aType &
Код:
testClass<aType>& testClass<aType>::operator = (const aType& hs){
    data = hs;
    return *this;
};

Последний раз редактировалось Aag; 14.06.2007 в 11:33..
 
Ответить с цитированием

  #4  
Старый 14.06.2007, 12:19
Аватар для pch
pch
Познающий
Регистрация: 22.10.2005
Сообщений: 37
Провел на форуме:
520745

Репутация: 141
По умолчанию

2 _Great_
У меня есть функция сравнения двух объектов класса testClass<int> и есть котструктор testClass<int>(int). Так что компилятор может привети оба операнда к типу testClass<int> и сравнить. Более того, если выкинуть все шаблоны и везде заменить aType на int (а testClass<int> b(4) на testClass b(4)), то всё именно так и работает.
Компялятор - gcc (win).

2 Aag
А где здесь копирование? Я же иницаализирую не элементом того же класса, а int-ом...
В любом случае, добавление явного оператора копирования ничего не меняет, те же ошибки
 
Ответить с цитированием

  #5  
Старый 14.06.2007, 23:07
Аватар для Aag
Aag
Познающий
Регистрация: 26.07.2005
Сообщений: 54
Провел на форуме:
47901

Репутация: 46
По умолчанию

Компильнул твой код из начала темы. Ни одной ошибки. Все работает без изменений.
Получил
Код:
a equals b
b equals a
Копилятор gcc 3.3.5 (*nix)

про оператор присваивания я не прав. здесь действительно инициализация идет.
 
Ответить с цитированием

  #6  
Старый 15.06.2007, 01:08
Аватар для pch
pch
Познающий
Регистрация: 22.10.2005
Сообщений: 37
Провел на форуме:
520745

Репутация: 141
По умолчанию

Пробовал на:
BSD: gcc version 3.4.2 [FreeBSD] 20040728
Linux: gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Win: gcc version 2.95.2 19991024 (release)
Win: gcc version 3.4.2 (mingw-special)

И вcе выдают более-менее одну и ту же ошибку.

Это однако ппц какой-то.
Можете привести что точно выводит это компилятор на gcc -v ? Мож там ключи какие хитрые подефолту?

Последний раз редактировалось pch; 15.06.2007 в 01:11..
 
Ответить с цитированием

  #7  
Старый 15.06.2007, 15:36
Аватар для Aag
Aag
Познающий
Регистрация: 26.07.2005
Сообщений: 54
Провел на форуме:
47901

Репутация: 46
По умолчанию

gcc -v: gcc version 3.3.5

Попробывал на mingw 3.4.5 под win действительно не работает.

Но при минимальных изменениях все работает под mingw 3.4.5
Код:
#include <iostream>

template <typename aType>
class testClass{
public:
       aType data;
       testClass(aType c): data(c) {};
       bool friend operator==(testClass<aType> a, testClass<aType> b){return a.data==b.data;} ;
};


int main(){
       int a=4;
       testClass<int> b(4);
       if (a==b) std::cout << "a equals b\n";
       if (b==a) std::cout << "b equals a\n";
};
то есть если внести описания друга внутрь класса.

Вот посмотри еще http://en.wikipedia.org/wiki/Barton-Nackman_trick

Последний раз редактировалось Aag; 15.06.2007 в 15:40..
 
Ответить с цитированием

  #8  
Старый 15.06.2007, 17:00
Аватар для pch
pch
Познающий
Регистрация: 22.10.2005
Сообщений: 37
Провел на форуме:
520745

Репутация: 141
По умолчанию

Ух-ты. Я просто в Ахуе. Огромный респект!
 
Ответить с цитированием

  #9  
Старый 16.06.2007, 15:36
Аватар для ZaCo
ZaCo
Banned
Регистрация: 20.06.2005
Сообщений: 880
Провел на форуме:
4610226

Репутация: 1332


По умолчанию

а так по-моему много проще:
operator int()
{
return data;
}
 
Ответить с цитированием

  #10  
Старый 16.06.2007, 16:00
Аватар для pch
pch
Познающий
Регистрация: 22.10.2005
Сообщений: 37
Провел на форуме:
520745

Репутация: 141
По умолчанию

2 ZaCo

Ну тогда уж не operator int(), а operator aType(), но в любом случае это - не то . Этот оператор преобразует оба операнда к типу aType (в данном случае - int), и сравнивает их как инты. А если в классе не одно поле (например, рац числа над типом int), то приведение к инту даст лажу (можно приводить в частном случае к флоату, но в общем шаблонном случае непонятно к чему приводить).

Убедиться, что оператор сравнения в классе testClass lдействительно не вызывается просто, достаточно добавить туда cout:
Код:
#include <iostream>
using namespace std;

template <class aType>
class testClass{
public:
	aType data;
	testClass(aType c): data(c) {}
	bool friend operator==<aType>(testClass<aType>, testClass<aType>);
	operator aType(){
		return data;
	}
};
template <class aType>
bool operator==(testClass<aType> a, testClass<aType> b){
	cout << "Operator == exucuted\n";
	return a.data==b.data;
}
int main(){
	int a=4;
	testClass<int> b(4);
	if (a==b) cout << "a equals b\n";
	if (b==a) cout << "b equals a\n";
}
Этот код не выведет фразу "Operator == exucuted" ни разу
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Про одно всё, про  одно..... Николь Болталка 20 01.02.2009 18:31
Про нас, про мужчин! SladerNon Болталка 27 21.02.2007 16:44
Про банеры, за которые деньги платят... temp_late Болталка 7 27.08.2006 05:54
Статья от novichka про АНтичат. Егорыч+++ Болталка 48 14.07.2006 17:09



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ