WWW.ИСХОДНИКИ.РУ cpp.sources.ru
java.sources.ru web.sources.ru soft.sources.ru
jdbc.sources.ru asp.sources.ru api.sources.ru

  Форум на исходниках
  C / C++ / Visual C++
  Наследование перегруженого operator =

СПРОСИТЬ  ОТВЕТИТЬ
профайл | регистрация | faq

Автор Тема:   Наследование перегруженого operator =
server_mouse опубликован 29-12-2001 17:24 MSK   Click Here to See the Profile for server_mouse   Click Here to Email server_mouse  
Есть класс с перегруженым оператором =. Делаю наследника, и тот почему-то не наследует эту перегрузку, пытаясь сделать binary copy. Попытка сделать его virtual не помогла. Неужто его нужно обязательно явно переопределять?
zAg опубликован 29-12-2001 19:36 MSK     Click Here to See the Profile for zAg  Click Here to Email zAg     
Я сначала подумал что это особенность VC (в CB таких проблем не было), но щас попробовал -
такая конструкция работает и там и там:

class base{
public:
base& __fastcall operator=(base &mc);
};

base& __fastcall base::operator=(base &mc)
{
return *this;
}

class derived:public base{
};

derived a,b;
a=b;

??

zAg опубликован 29-12-2001 19:37 MSK     Click Here to See the Profile for zAg  Click Here to Email zAg     
Вызывается именно base::operator=
server_mouse опубликован 03-01-2001 10:12 MSK     Click Here to See the Profile for server_mouse  Click Here to Email server_mouse     
Вот такой код не работает!
//------------- str.h ----------------
class CStr
{
public:
char* str;
CStr& __fastcall operator = (const char* _str);
CStr& __fastcall operator = (CStr& _str);
operator LPCTSTR () const;
virtual ~CStr();
};

class CStr2:public CStr
{
public:
CStr2();
virtual ~CStr2();
};
//----------------------------------
//----------- str.cpp --------------
#include "str.h"
CStr& __fastcall CStr::operator = (CStr& _str)
{
return *this;
}

CStr& __fastcall CStr::operator = (const char* _str) //Çàãðóçêà èç ñòðîêè
{
//Тут всякая шняга
return *this;
}

CStr::operator LPCTSTR () const
{
return str;
}
//--------------------------------
//Конструкторы/деструкторы не описывал.
//Они вам нужны???

main()
{
CStr str1;
str1="test1";
CStr2 str2;
str2="test";
}

Именно на последнюю строку и ругается компилятор:
error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'char [5]' (or there is no acceptable conversion)
Как я понял он пытается сделать побайтное копирование...
Вправте ручки.

Valery опубликован 03-01-2001 11:09 MSK     Click Here to See the Profile for Valery  Click Here to Email Valery     
2server_mouse:
ой, тяжко, конечно после нового года вспоминать всякое, но тем не менее: оператор= как и конструктор предоставляется компилятором по умолчанию и не наследуется, вот не помню, можно ли его делать виртуальным. А поэтому тебе придется описывать в производном классе оператор присваивания с такой же сигнатурой, если ты хочешь, чтобы срабатывал такой же синтаксис. и ужо внутри перевызывать оператор присваивания для базового класса.
Valery опубликован 03-01-2001 11:12 MSK     Click Here to See the Profile for Valery  Click Here to Email Valery     
проверил, делать виртуальным его можно, но вот теперь не могу понять - нафига :) тяжко...
Valery опубликован 03-01-2001 11:22 MSK     Click Here to See the Profile for Valery  Click Here to Email Valery     
что значит, все-таки, чашечка хорошего кофе!
и нужен и вполне применим, даже в твоем случае:
CStr *s = new CStr2;
*s = "aaaaaaaaa";

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


sergeyMJ опубликован 03-01-2001 12:41 MSK     Click Here to See the Profile for sergeyMJ  Click Here to Email sergeyMJ     
А вот такой код работать не будет,

CString s1;
s1 = "Ex2" + "Ex2";

А такой будет:

CString s2= "Hello";
s1 = "Ex2" + s2+ "Ex2";

Valery опубликован 03-01-2001 13:12 MSK     Click Here to See the Profile for Valery  Click Here to Email Valery     
при чем здесь это?
здесь ты присваиваешь результать оператора +, а он как известно возвращает CString, то бишь объект того же класса. Уж для него-то компилятор способен состряпать конструктор копии, правда в этом случае это не надо, он описан в классе CString. Первый твой пример не работает потому что нет (да и не может быть) внешнего оператора +, который бы складывал два указателя на char в стороку типа CString.
А во втором случае все достаточно штатно - к объекту CString прибавляется LPCTSTR, а потом еще раз, все за счет вот этих двух объявлений:

friend CString operator +( const CString& string, LPCTSTR lpsz );
throw( CMemoryException );

friend CString operator +( LPCTSTR lpsz, const CString& string );
throw( CMemoryException );

Вот собственно и все. А в чем траблы?

sergeyMJ опубликован 03-01-2001 13:41 MSK     Click Here to See the Profile for sergeyMJ  Click Here to Email sergeyMJ     
А почему мы не можем перегрузить
friend CString operator +( LPCTSTR lpsz, LPCTSTR lpsz );
throw( CMemoryException );

zAg опубликован 03-01-2001 14:02 MSK     Click Here to See the Profile for zAg  Click Here to Email zAg     
2server_mouse:
И в самом самом деле чето не пашет...Если только так:
(CStr&)str2="test";
и если нужно определить CStr2::operator CStr()
но это конечно не то...
кстати оказывается в описанной мной схеме работает только derived::operator=(derived),а derived::operator=(base) работать уже не будет >:[ Хотя по идее именно он работать и должен.

ps. И вообще нафиг тебе наследник для строкового класса? Неужели одним классом нельзя обойтись?

Valery опубликован 03-01-2001 14:03 MSK     Click Here to See the Profile for Valery  Click Here to Email Valery     
стандарт языка требует, чтобы при перегрузке бинарных операторов в виде внешней функции хотя бы один из их параметров был _обязательно_ пользовательским типом.
Требование введено для того, чтобы язык был _расширяемым_, а не _меняющимся_.
zAg опубликован 03-01-2001 14:27 MSK     Click Here to See the Profile for zAg  Click Here to Email zAg     
И вообще перегрузка операторов(особенно =) ИМХО снижает наглядность. Например будут *str1,*str2 ,забудешь что это указатели и напишешь str1=str2 думая что скопируются строки - получится неприятность :)
Я в подобных случаях вместо operator= определяю метод Assign(школа VCL :)) Тогда все наследуется как надо:
str2.Assign("test") или в случае указателя : str2->Assign("test") - по-моему неплохо смотрится :)
да и ошибок никогда не будет.
Valery опубликован 03-01-2001 14:53 MSK     Click Here to See the Profile for Valery  Click Here to Email Valery     
Хорошо подобранный набор операций имхо наоборот повысит наглядность, хотя, как и в любом деле здесь необходимо чувство меры. А насчет примера с указателями на символ вместо сторок - давно уж говорится не думайте, что это строки. Я если их использую, то только где-то в потрохах классов или когда необходимо интерфейс а-ля Сишка предоставить. А так предпочитаю эстээлевские стороки (в этом месте могла бы быть ваша реклама :)
zAg опубликован 03-01-2001 15:44 MSK     Click Here to See the Profile for zAg  Click Here to Email zAg     
Под наглядностью я имел в виду вот что: наткнувшись где то в недрах кода на запись a=b ничего нельзя сказать что здесь реально делается :то ли это binary copy то ли перегруженный оператор= или может a и b указатели на объекты?
А вот в случае a.Assign(b) или a->Assign(b) - сразу понятно ,что:
1. объект a копирует объект b явно определенным способом
2. cами ли это объекты или указатели на них

ps. для строкового класса возможно имеет смысл определить operator=, но в общем случае для копирования лучше завести спец. метод (ИМХО)

Valery опубликован 03-01-2001 16:04 MSK     Click Here to See the Profile for Valery  Click Here to Email Valery     
присваивание нагляднее в том плане, что это стандартная ++-ность, не суть важно как при этом происходит копирование - глубокое с использованием конструкторов копирования всех вложенных сущностей или простое бинарное. Меня это не должно волновать - класс должен быть спроектирован так чтобы делать это без сюрпризов. По поводу указателей - отдельная тема, очень емкая.
Функция Assign() в твоем случае - лишь замена синтаксиса, привычная тебе, тот кто столкнется с ней впервые, также полезет в исходники функции, чтобы понять чего она делает. Все вышесказанное также имхо. Вообще мы с тобой начинаем спорить о вкусах, а это занятие бесперспективное.

СПРОСИТЬ  ОТВЕТИТЬ
Перейти:


E-mail | WWW.ИСХОДНИКИ.RU

Powered by: Ultimate Bulletin Board, Freeware Version 5.10a
Purchase our Licensed Version- which adds many more features!
© Infopop Corporation (formerly Madrona Park, Inc.), 1998 - 2000.