Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Оператор присваивания наследуется?


Автор: Dims 22.12.2009, 19:23
Почему не наследуется оператор присваивания в данном примере?

Код

template <class T> 
class Reference {

    T* p;


public:

    Reference();
    Reference &operator=(const Reference &ano);
    Reference &operator=(T* p);

};

typedef Reference<int> R2;

class R3 : public Reference<int> {
};


int _tmain(int argc, _TCHAR* argv[])
{

    Reference<int> r1;
    R2 r2;
    R3 r3;

    int *p;

    r1=p;
    r2=p;
    r3=p; // ошибка: Error    1    error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int *' (or there is no acceptable conversion)



    return 0;
}


Автор: mes 22.12.2009, 19:42
http://forum.vingrad.ru/index.php?showtopic=268422&view=findpost&p=1933714

Автор: Dims 22.12.2009, 19:48
Спасибо! Так я не понял, using в такой функции уже сделали что ли?

Автор: mes 22.12.2009, 19:51
Цитата(Dims @  22.12.2009,  18:48 Найти цитируемый пост)
Так я не понял, using в такой функции уже сделали что ли? 

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

P.S. причина в том, что обсуждаемый оператор специальный и на него распространяются некоторые обязательства, в частности то, что этот оператор для каждого класса будет неявно сгенерирован компилятором, если пользователь не опишет его явно. 

Автор: Dims 24.12.2009, 22:29
Ха! Вроде бы using помогает не полностью! Вопрос снова открыт!

Вот пример

Код

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

#include "stdafx.h"

template <class T> 
class Reference {

    T* p;


public:

    Reference();
    Reference &operator=(const Reference &ano);
    Reference &operator=(T* p);

};

typedef Reference<int> R2;

class R3 : public Reference<int> {
public:
    using Reference<int>::operator=;
};


int _tmain(int argc, _TCHAR* argv[])
{

    Reference<int> r1;
    R2 r2;
    R3 r3;

    int *p;

    r1=p;
    r2=p;
    r3=p;

    Reference<int>(r1=p);
    R2(r2=p);
    R3(r3=p); // Error    1    error C2440: '<function-style-cast>' : cannot convert from 'Reference<T>' to 'R3'    

    return 0;
}



Автор: mes 25.12.2009, 00:40
Цитата(Dims @  24.12.2009,  21:29 Найти цитируемый пост)
Ха! Вроде бы using помогает не полностью! Вопрос снова открыт!

ну тут проблема уже не с оператором присваивания, а с конструктором.. они в текущем стандарте не наследуются..

Можно узнать зачем такое извращение ? думаю должен быть способ достичь цели более естественным путем.
smile

Автор: Dims 27.12.2009, 10:49
Какой именно конструктор тут не отнаследовался?

Цитата(mes @  25.12.2009,  00:40 Найти цитируемый пост)
Можно узнать зачем такое извращение ? 

Не извращение, а нормальное для ООП желание использовать наследование...

Я хочу завернуть интерфейсы DirectShow в свои классы так, чтобы было проще ими пользоваться...

Автор: mes 27.12.2009, 13:30
Цитата(Dims @  27.12.2009,  09:49 Найти цитируемый пост)
Какой именно конструктор тут не отнаследовался?

нет конструктора  R3 (Reference<int> const& );

Цитата(Dims @  27.12.2009,  09:49 Найти цитируемый пост)
Не извращение, а нормальное для ООП желание использовать наследование...

имхо Вам стоит еще раз осмотреться, правильное ли направление Вы выбрали..  smile 







Автор: Dims 29.12.2009, 23:00
Цитата(mes @  27.12.2009,  13:30 Найти цитируемый пост)
нет конструктора  R3 (Reference<int> const& );

Разве компилятор не генерит его автоматически?

Автор: bsa 30.12.2009, 11:45
Цитата(Dims @  29.12.2009,  23:00 Найти цитируемый пост)
Разве компилятор не генерит его автоматически? 

А с какого это бодуна он должен генерировать подобное? Автоматически генерятся R3::R3(const R3 &) и R3& R3::operator=(const R3&), если не объявлены явно.

Автор: mes 30.12.2009, 13:29
Цитата(Dims @  29.12.2009,  22:00 Найти цитируемый пост)
Разве компилятор не генерит его автоматически? 

добавлю к bsa, что в общем случае это невозможно - построить наследника на основе базового класса, так как наследник может обладать доп. данными.
ну а частные случаи, когда наследники, просто "оборачивают" базовый класс, не являются достаточным основанием для (исключительной из  общего правила) генерации.



 

Автор: Dims 30.12.2009, 22:03
В общем, если суммировать, то следует просто сказать, что оператор присваивания не наследуется и using делу не поможет.

Автор: mes 30.12.2009, 23:17
Цитата(Dims @  30.12.2009,  21:03 Найти цитируемый пост)
В общем, если суммировать, то следует просто сказать, что оператор присваивания не наследуется и using делу не поможет. 

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

в теме мало информации о Ваших задаче и целях, но попробую предположить, что для решения Вашей может подойти CRTP :
http://insidecpp.ru/patterns/curiously_recurring_template_pattern/




Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)