Russian Qt Forum

Qt => Общие вопросы => Тема начата: dr_Begemot от Март 17, 2010, 14:23



Название: Про наследование и перегрузку операторов
Отправлено: dr_Begemot от Март 17, 2010, 14:23
Код:
class A{
public:
    void setAny(QString){
        //...
    }

};

class B : public A {
private:
    void setAny(){
        QString str = "any";
        setAny(str);
    }
};

Компилятор пишет function does not take 1 arguments, как решение, написать:
Код:
class B : public A {
private:
    void setAny(){
        QString str = "any";
        A::setAny(str);
    }
};
Вопрос: почему функция не перегружается? Т.е. setAny(QString) попросту пропадает, т.е. в функции main нельзя будет сделать так:
Код:
    B val;
    val.setAny("any");

Поясните плиз, что в данном случае происходит с функцией setAny?

Спасибо)


Название: Re: Про наследование и перегрузку операторов
Отправлено: kuzulis от Март 17, 2010, 14:26
Страуструп и другие авторы в помощь! :)

Там всё объясняется


Название: Re: Про наследование и перегрузку операторов
Отправлено: lit-uriy от Март 17, 2010, 14:38
>>Страуструп и другие авторы в помощь!
если ты знаток Страуструпа, то пиши сразу, год издания, глава, страница.


Название: Re: Про наследование и перегрузку операторов
Отправлено: dr_Begemot от Март 17, 2010, 14:44
>>Страуструп и другие авторы в помощь!
если ты знаток Страуструпа, то пиши сразу, год издания, глава, страница.

+1
Решение любой проблемы можно найти в книге или документации, вопрос в том, что зачем тогда форум? По поводу Страуструпа, вполне возможно, что там и есть ответ на мой вопрос, но я не знаю, по какой тематике искать - наследование классов?


Название: Re: Про наследование и перегрузку операторов
Отправлено: Авварон от Март 17, 2010, 15:01
это сделано для оптимизации компилятора - он не включает в рассмотрение полиморфизма функции из базовых классов (в полиморфизме участвуют только функции класса, от которого идет вызов, в данном случае - наследника). Выход - напрямую указывать меймспейс val.A::setAny("any");


Название: Re: Про наследование и перегрузку операторов
Отправлено: Sergey B. от Март 17, 2010, 17:15
А причём тут полиморфизм?
В С++ полиморфизм работает только с виртуальными функциями, через указатель на базовый класс.
Тут же речь идёт о сокрытии. Т.е. функция класса наследника, перекрывает функцию класса предка.


Название: Re: Про наследование и перегрузку операторов
Отправлено: Sergey B. от Март 17, 2010, 17:19
Страница 353, там вкратце, более подробно если интересно, можно поискать самим...

Код:
Как правило, самым понятным решением является использование в производном 
классе только открытых членов его базового класса. Например:
void Manager::print () const
{
Employer::print (); // печать информации о сотруднике
cout<<level; // печать информации, относящейся только к менеджеру

}
Обратите внимание, что должен использоваться оператор ::, потому что print () была
замещена в Manager. Такое повторное использование имен является типичным.


Название: Re: Про наследование и перегрузку операторов
Отправлено: Kolobok от Март 17, 2010, 17:50
Страница 353, там вкратце, более подробно если интересно, можно поискать самим...

Разговор идет о перегрузке, а не о замещении. Сигнатура у setAny(QString) и setAny() разная. Для компилятора они должны выглядеть как две ничем друг с другом не связанные функции.


Название: Re: Про наследование и перегрузку операторов
Отправлено: Sergey B. от Март 17, 2010, 17:58
Так функции с разными сигнатурами, они же разные...
Что-то я упустил, погнал в сторону сокрытия...


Название: Re: Про наследование и перегрузку операторов
Отправлено: Sergey B. от Март 17, 2010, 18:05
А если  в начале класса  наследника написать:

Код:
using A::setAny;

Тогда A::setAny(QString) становится доступна в классе B, вводится в область видимости класса B и участвует в перегрузке, правда только если она не private в базовом классе.

Код:
Функции, объявленные в различных областях видимости (не пространствах имен), 
не являются перегруженными. Например:
void f[in t);
void g ()
{
void f (double);
/(/); // вызывается f (double)
}
Ясно, что f(int) была бы идеальным соответствием для/(/), но в данной области види-
мости находится только f (double).


Название: Re: Про наследование и перегрузку операторов
Отправлено: dr_Begemot от Март 18, 2010, 10:14
А если  в начале класса  наследника написать:

Код:
using A::setAny;

Тогда A::setAny(QString) становится доступна в классе B, вводится в область видимости класса B и участвует в перегрузке, правда только если она не private в базовом классе.

Код:
Функции, объявленные в различных областях видимости (не пространствах имен), 
не являются перегруженными. Например:
void f[in t);
void g ()
{
void f (double);
/(/); // вызывается f (double)
}
Ясно, что f(int) была бы идеальным соответствием для/(/), но в данной области види-
мости находится только f (double).


Интересное решение, спасибо)
а если в базовом классе есть несколько функций setAny с разными параметрами, то при написании
Код:
using A::setAny;
в классе наследнике они все участвуют в перегрузке?


Название: Re: Про наследование и перегрузку операторов
Отправлено: Igors от Март 18, 2010, 11:23
Вопрос: почему функция не перегружается? Т.е. setAny(QString) попросту пропадает, т.е. в функции main нельзя будет сделать так:
Код:
    B val;
    val.setAny("any");

Поясните плиз, что в данном случае происходит с функцией setAny?
B::setAny объявлена как private, поэтому вызов val.setAny невозможен и "using" не поможет. Позвать A::setAny можно так
Код:
(static_cast <A &> (val)).setAny("any");
Хотя я человек темный и всю жизнь пользуюсь
Код:
((A &) val).setAny("any");
:)


Название: Re: Про наследование и перегрузку операторов
Отправлено: Sergey B. от Март 20, 2010, 09:25
Вопрос: почему функция не перегружается? Т.е. setAny(QString) попросту пропадает, т.е. в функции main нельзя будет сделать так:
Код:
    B val;
    val.setAny("any");

Поясните плиз, что в данном случае происходит с функцией setAny?
B::setAny объявлена как private, поэтому вызов val.setAny невозможен и "using" не поможет. Позвать A::setAny можно так
Код:
(static_cast <A &> (val)).setAny("any");
Хотя я человек темный и всю жизнь пользуюсь
Код:
((A &) val).setAny("any");
:)

Изврат какой-то :)

В классе предке она public, поэтому using будет работать, я же писал, что работает - только если она не приватная.

@dr_Begemot
Да все паблин функции будут участвовать в перегрузке, но если есть такая же функция (сигнатура) в классе наследнике - она заместит предка.

И ещё
Код:
using A::setAny;
надо писать после спецификаторов доступа (public:, private:)


Название: Re: Про наследование и перегрузку операторов
Отправлено: MoPDoBoPoT от Март 20, 2010, 14:10
Изврат какой-то :)
Ты невнимательно прочитал (:
Igors писал про вызов setAny(QString) из вне класса B:
Код:
    B val;
    val.setAny("any");


Название: Re: Про наследование и перегрузку операторов
Отправлено: Sergey B. от Март 20, 2010, 18:13
Понятно.