Russian Qt Forum
Ноябрь 17, 2024, 04:10 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Про наследование и перегрузку операторов  (Прочитано 7797 раз)
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?

Спасибо)
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Март 17, 2010, 14:26 »

Страуструп и другие авторы в помощь! Улыбающийся

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

ArchLinux x86_64 / Win10 64 bit
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #2 : Март 17, 2010, 14:38 »

>>Страуструп и другие авторы в помощь!
если ты знаток Страуструпа, то пиши сразу, год издания, глава, страница.
Записан

Юра.
dr_Begemot
Гость
« Ответ #3 : Март 17, 2010, 14:44 »

>>Страуструп и другие авторы в помощь!
если ты знаток Страуструпа, то пиши сразу, год издания, глава, страница.

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

Сообщений: 3260


Просмотр профиля
« Ответ #4 : Март 17, 2010, 15:01 »

это сделано для оптимизации компилятора - он не включает в рассмотрение полиморфизма функции из базовых классов (в полиморфизме участвуют только функции класса, от которого идет вызов, в данном случае - наследника). Выход - напрямую указывать меймспейс val.A::setAny("any");
Записан
Sergey B.
Программист
*****
Offline Offline

Сообщений: 544



Просмотр профиля WWW
« Ответ #5 : Март 17, 2010, 17:15 »

А причём тут полиморфизм?
В С++ полиморфизм работает только с виртуальными функциями, через указатель на базовый класс.
Тут же речь идёт о сокрытии. Т.е. функция класса наследника, перекрывает функцию класса предка.
Записан
Sergey B.
Программист
*****
Offline Offline

Сообщений: 544



Просмотр профиля WWW
« Ответ #6 : Март 17, 2010, 17:19 »

Страница 353, там вкратце, более подробно если интересно, можно поискать самим...

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

}
Обратите внимание, что должен использоваться оператор ::, потому что print () была
замещена в Manager. Такое повторное использование имен является типичным.
« Последнее редактирование: Март 17, 2010, 18:10 от Sergey B. » Записан
Kolobok
Гость
« Ответ #7 : Март 17, 2010, 17:50 »

Страница 353, там вкратце, более подробно если интересно, можно поискать самим...

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

Сообщений: 544



Просмотр профиля WWW
« Ответ #8 : Март 17, 2010, 17:58 »

Так функции с разными сигнатурами, они же разные...
Что-то я упустил, погнал в сторону сокрытия...
« Последнее редактирование: Март 17, 2010, 18:13 от Sergey B. » Записан
Sergey B.
Программист
*****
Offline Offline

Сообщений: 544



Просмотр профиля WWW
« Ответ #9 : Март 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).
« Последнее редактирование: Март 17, 2010, 18:07 от Sergey B. » Записан
dr_Begemot
Гость
« Ответ #10 : Март 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;
в классе наследнике они все участвуют в перегрузке?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Март 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");
Улыбающийся
Записан
Sergey B.
Программист
*****
Offline Offline

Сообщений: 544



Просмотр профиля WWW
« Ответ #12 : Март 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:)
« Последнее редактирование: Март 20, 2010, 09:27 от Sergey B. » Записан
MoPDoBoPoT
Гость
« Ответ #13 : Март 20, 2010, 14:10 »

Изврат какой-то Улыбающийся
Ты невнимательно прочитал (:
Igors писал про вызов setAny(QString) из вне класса B:
Код:
    B val;
    val.setAny("any");
Записан
Sergey B.
Программист
*****
Offline Offline

Сообщений: 544



Просмотр профиля WWW
« Ответ #14 : Март 20, 2010, 18:13 »

Понятно.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.123 секунд. Запросов: 23.