Russian Qt Forum

Программирование => С/C++ => Тема начата: CuteBunny от Июль 19, 2012, 09:58



Название: using?
Отправлено: CuteBunny от Июль 19, 2012, 09:58
Объясните, пожалуйста, следующий момент:

Код
C++ (Qt)
class Parent
{
   public:
       virtual void action( const char how ){ this->action( &how ); }
       virtual void action( const char * how ) = 0;
};
 
class Son : public Parent
{
   public:
       using Parent::action; // Why should i write this line?
       void action( const char * how ){ printf( "Action: %c\n", *how ); }
};
int main( int argc, char** argv )
{
   Son s = Son();
   s.action( 'a' );
   return 0;
}
 

Почему, если закомментировать строку using Parent::action; у класса Son не будет виден метод родительского класса action с const char и программа не скомпилируется?

p.s.: пример нашел на stackoverflow, там есть объяснение, но ни понятнооо


Название: Re: using?
Отправлено: mutineer от Июль 19, 2012, 10:12
Когда ты определяешь action в наследнике, то происходит перекрытие всех методов action родителя, то есть они становятся не видны из наследника. Чтобы перекрытия не было и нужен using


Название: Re: using?
Отправлено: CuteBunny от Июль 19, 2012, 10:15
Спасибо


Название: Re: using?
Отправлено: Akon от Июль 19, 2012, 11:11
Замещение функции в наследнике происходит по имени (а не по сигнатуре). Вот пример, когда это полезно:
Код:
class Parent
{
public:
virtual Parent* clone() const { return new Parent(); }
};

class Son : public Parent
{
public:
// Обратите внимание, возвращается Son* а не Parent*
virtual Son* clone() const { return new Son(); } 
};

...
Son son;
Son* clone = son.clone();  // соответственно, никакого даункаста

Сейчас я не знаю (забыл или не знал вовсе), почему именно такое поведение у компиляторов (замещение по имени, а не по сигнатуре) и сходу найти веское объяснение не получается. Кто подскажет?


Название: Re: using?
Отправлено: mutineer от Июль 19, 2012, 11:18
Возвращаемое значение не входит в сигнатуру. Потому что просто по вызову someFun(); невозможно определить результат какого типа ты хочешь получить


Название: Re: using?
Отправлено: Igors от Июль 19, 2012, 11:36
Замещение функции в наследнике происходит по имени (а не по сигнатуре). Вот пример, когда это полезно:
Сомневаюсь что число таких примеров можно увеличить :) Возвращаемый тип должен быть "identical or covariant", это единственное послабление.

Возвращаемое значение не входит в сигнатуру. Потому что просто по вызову someFun(); невозможно определить результат какого типа ты хочешь получить
Не входит но компилятором контролируется. Напр нельзя вернуть int * из Son::Clone


Название: Re: using?
Отправлено: Swa от Июль 19, 2012, 15:11
А почему происходит перекрытие? Ведь Son лишь реализует абстрактный метод
Код:
action( const char *)
, а
Код:
action( const char how )
он наследует от родителя.


Название: Re: using?
Отправлено: mutineer от Июль 19, 2012, 15:19
В этом и состоит суть перекрытия - если ребенок определяет у себя метод с таким же именем, то родительские методы (с этим же именем) уже недоступны становятся


Название: Re: using?
Отправлено: Swa от Июль 19, 2012, 15:40
Спасибо, теперь понял. Не сразу допёр, что перекрытие не учитывает сигнатуру метода.


Название: Re: using?
Отправлено: mutineer от Июль 19, 2012, 15:47
Спасибо, теперь понял. Не сразу допёр, что перекрытие не учитывает сигнатуру метода.

Какбе в теме об этом упоминалось