Наследование operator=
От: PaulV  
Дата: 31.07.02 10:10
Оценка:
Столкнулся со следущей проблемой:
template<typename _Tp>
class aa
{
        _Tp* _d;
public:

        aa& operator= (_Tp* d) { _d=d; return *this; }
};

class bb : public aa<int>
{
};

int main ()
{
        aa<int> a;
        bb              b;
        int             val = 5;

        a = &val;
        b = &val;
}


Компилятор на строке "b = &val;" естественно выдает ошибку "Could not find a match for 'bb::operator =(int *)' in function main()". Объяснение этому факту в стандарте (если я ошибаюсь — поправьте):

13.5.3 Assignment [over.ass]

1 An assignment operator shall be implemented by a non-static member
function with exactly one parameter. Because a copy assignment opera-
tor operator= is implicitly declared for a class if not declared by
the user (_class.copy_), a base class assignment operator is always
hidden by the copy assignment operator of the derived class.



Вопрос: Как это обойти? Т.е. хочется определить в базовом классе оператор присваивания, а во всех дочерних им пользоваться.

Вариант
typedef aa<int> bb;

не подходит, т.к. bb может содержать дополнительные методы.

Заранее спасибо!
Re: Наследование operator=
От: dupamid Россия  
Дата: 31.07.02 10:30
Оценка:
Здравствуйте PaulV, Вы писали:

PV>Столкнулся со следущей проблемой:

PV>
PV>template<typename _Tp>
PV>class aa
PV>{
PV>        _Tp* _d;
PV>public:

PV>        aa& operator= (_Tp* d) { _d=d; return *this; }
PV>};

PV>class bb : public aa<int>
PV>{
PV>};

PV>int main ()
PV>{
PV>        aa<int> a;
PV>        bb              b;
PV>        int             val = 5;

PV>        a = &val;
PV>        b = &val;
PV>}
PV>


PV>Компилятор на строке "b = &val;" естественно выдает ошибку "Could not find a match for 'bb::operator =(int *)' in function main()". Объяснение этому факту в стандарте (если я ошибаюсь — поправьте):

PV>
PV>13.5.3 Assignment [over.ass]

PV>1 An assignment operator shall be implemented by a non-static member

PV> function with exactly one parameter. Because a copy assignment opera-
PV> tor operator= is implicitly declared for a class if not declared by
PV> the user (_class.copy_), a base class assignment operator is always
PV> hidden by the copy assignment operator of the derived class.

PV>


PV>Вопрос: Как это обойти? Т.е. хочется определить в базовом классе оператор присваивания, а во всех дочерних им пользоваться.


PV>Вариант

PV>
PV>typedef aa<int> bb;
PV>

PV>не подходит, т.к. bb может содержать дополнительные методы.

PV>Заранее спасибо!


Видимо надо написать так:

class bb : public aa<int>
{
public:
    using aa<int>::operator=;
};


Но MS Visual C++ .NET этого не понимает и продолжает ругаться
Re: Наследование operator=
От: Alik Украина  
Дата: 31.07.02 10:30
Оценка:
Здравствуйте PaulV, Вы писали:

PV>Столкнулся со следущей проблемой:

PV>
PV>template<typename _Tp>
PV>class aa
PV>{
PV>        _Tp* _d;
PV>public:

PV>        aa& operator= (_Tp* d) { _d=d; return *this; }
PV>};

PV>class bb : public aa<int>
PV>{
PV>};

PV>int main ()
PV>{
PV>        aa<int> a;
PV>        bb              b;
PV>        int             val = 5;

PV>        a = &val;
PV>        b = &val;
PV>}
PV>


PV>Компилятор на строке "b = &val;" естественно выдает ошибку "Could not find a match for 'bb::operator =(int *)' in function main()". Объяснение этому факту в стандарте (если я ошибаюсь — поправьте):

PV>
PV>13.5.3 Assignment [over.ass]

PV>1 An assignment operator shall be implemented by a non-static member

PV> function with exactly one parameter. Because a copy assignment opera-
PV> tor operator= is implicitly declared for a class if not declared by
PV> the user (_class.copy_), a base class assignment operator is always
PV> hidden by the copy assignment operator of the derived class.

PV>


Объяснение этому факту очень простое: операторы не наследуются.

PV>Вопрос: Как это обойти? Т.е. хочется определить в базовом классе оператор присваивания, а во всех дочерних им пользоваться.


Можно определять операторы присваивания в дочерних классах, а в имплементации приводить операнды к родителю и, соответственно, вызывать оператор присваивания у родителя.
С уважением. Алик.
Re[2]: Наследование operator=
От: Vi2 Удмуртия http://www.adem.ru
Дата: 31.07.02 10:51
Оценка:
Здравствуйте Alik, Вы писали:

A>Объяснение этому факту очень простое: операторы не наследуются.


Не "операторы не наследуются", а видимость оператор= перекрывается либо указываемым явно оператором= в дочернем классе либо генерируемым по умолчанию, если таковой не указан. Поэтому он не виден.

Точно так же как перекрываются все перегруженные функции базового класса при указании хотя бы одной с таким именем в дочернем.


Измени в примере = на < (семантика не волнует пока), и ошибки не получишь.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[3]: Наследование operator=
От: Alik Украина  
Дата: 31.07.02 11:54
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>Здравствуйте Alik, Вы писали:


A>>Объяснение этому факту очень простое: операторы не наследуются.


Vi2>Не "операторы не наследуются", а видимость оператор= перекрывается либо указываемым явно оператором= в дочернем классе либо генерируемым по умолчанию, если таковой не указан. Поэтому он не виден.


Vi2>Точно так же как перекрываются все перегруженные функции базового класса при указании хотя бы одной с таким именем в дочернем.


Согласен, формулировка не точная. Выдернутая из контекста она вообще получает свой достаточно общий и уже некорректный смысл. Но результат — что в лоб, что по лбу. Скажем так: поскольку для любого класса генерируется свой оператор присваивания (и это поведение компилятора вполне соответствует стандарту), класс наследник всегда имеет свои оператор присваивания, отличный от родительского.
С уважением. Алик.
Re[4]: Наследование operator=
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.08.02 12:50
Оценка:
Здравствуйте Alik, Вы писали:

A> Согласен, формулировка не точная. Выдернутая из контекста она вообще получает свой достаточно общий и уже некорректный смысл. Но результат — что в лоб, что по лбу. Скажем так: поскольку для любого класса генерируется свой оператор присваивания (и это поведение компилятора вполне соответствует стандарту), класс наследник всегда имеет свои оператор присваивания, отличный от родительского.


Но,как верно заметил dupamid, operator = из базового класса можно вытащить через using.
Re[5]: Наследование operator=
От: Ридош Вадим  
Дата: 01.08.02 16:17
Оценка:
Здравствуйте DarkGray, Вы писали:

DG>Но,как верно заметил dupamid, operator = из базового класса можно вытащить через using.


Не вижу смысла его вытаскивать
Он всё равно вызовется — при генерации operator= сначала вызывается operator= для всех базовых классов, а затем — для всех member-ов, добавленных в этом классе
Re[6]: Наследование operator=
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.08.02 16:22
Оценка:
Здравствуйте Ридош Вадим, Вы писали:

DG>>Но,как верно заметил dupamid, operator = из базового класса можно вытащить через using.


РВ>Не вижу смысла его вытаскивать

РВ>Он всё равно вызовется — при генерации operator= сначала вызывается operator= для всех базовых классов, а затем — для всех member-ов, добавленных в этом классе

Так operator = не всегда же определяет конструктор копии... Так в примере из начального письма было видно, что в данном случае operator = выступает в качестве operator-а "преобразования" из int-а в класс
Re[6]: Наследование operator=
От: Андрей Тарасевич Беларусь  
Дата: 01.08.02 16:40
Оценка:
Здравствуйте Ридош Вадим, Вы писали:

DG>>Но,как верно заметил dupamid, operator = из базового класса можно вытащить через using.


РВ>Не вижу смысла его вытаскивать

РВ>Он всё равно вызовется — при генерации operator= сначала вызывается operator= для всех базовых классов, а затем — для всех member-ов, добавленных в этом классе

Речь идет об операторе присваивания из постороннего указательного типа, а не о копирующем операторе присваивания.
Best regards,
Андрей Тарасевич
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.