Форум программистов, компьютерный форум CyberForum.ru

Наследование, и перегрузки методов - C++

Восстановить пароль Регистрация
 
Bers
Заблокирован
05.12.2011, 02:51     Наследование, и перегрузки методов #1
Вопрос: есть ли какие нибудь красивые решения данной проблемы?

Рассмотрим ниже представленный код:
C++
1
2
3
4
5
6
7
8
9
class Test1
{
    public: void Print(const char* text) { std::cout<<text; }
};
 
class Test2:public Test1
{
    public: void Print(const Test2& rhs) { std::cout<<"text\n"; }
};
Я рассчитываю, что Test2 унаследует весь функционал Test1
И я смогу им свободно пользоваться. Но это не совсем так...
C++
1
2
3
4
5
6
7
8
9
int main()
{
    Test2 t;
    t.Print(t);     //можно
    
    t.Print("sdf"); //error C2664: Test2::Print: 
                    //невозможно преобразовать параметр
                    //1 из 'const char [4]' в 'const Test2 &'
}
Все дело в том, что если в наследнике имеется одноименный метод, то он скрывает собой все перегрузки базового метода.
Теперь, снаружи методы базового класса в обычном виде уже не доступны.

Можно вылечить двумя способами. Оба способа на мой взгляд, ну по меньше мере не красивы.

C++
1
2
3
4
5
6
7
8
//первый способ:
int main()
{
    Test2 t;
    t.Print(t);     //можно
    
    t.Test1::Print("sdf"); //можно
}
Помимо ужасной на вид записи, такой способ имеет более серьёзные недостатки.
Например, вынуждает пользователя знать внутреннее устройство класса (знать, от чего он там унаследовался). И серьёзно затрудняет проектирование архитектуры на шаблонах.
Приходится повсюду таскать за собой "знание о типе, от которого был унаследован класс", и постоянно контролировать какие методы "дополниловки", а какие - "наследство от папочки".


Второй способ сводит на нет надобность в самом наследовании (хотя, мне он видится более предпочтительным в такой ситуации)


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Test1
{
public: void Print(const char* text) { std::cout<<text; }
};
 
class Test2:public Test1
{
public: void Print(const Test2& rhs) { std::cout<<"text\n"; }
        void Print(const char* text) { Test1::Print(text); }
};
 
int main()
{
    Test2 t;
    t.Print(t);     //можно
    
    t.Print("sdf"); //теперь можно
}
Помимо того, что приходится дублировать код, данный способ ещё пахнет оверхедом.
То есть,функция запускает функцию. Может быть компилятор это оптимизирует. А может быть и нет.


Вопрос: есть ли какие нибудь красивые решения данной проблемы?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
greeezz
272 / 165 / 4
Регистрация: 10.07.2011
Сообщений: 441
05.12.2011, 03:08     Наследование, и перегрузки методов #2
я дико извиняюсь, я что мешает в классе Test1 имя функции сделать другим? printChar например ?
Bers
Заблокирован
05.12.2011, 03:27  [ТС]     Наследование, и перегрузки методов #3
делете (глюк сервака)

Добавлено через 2 минуты
Цитата Сообщение от greeezz Посмотреть сообщение
я дико извиняюсь, я что мешает в классе Test1 имя функции сделать другим? printChar например ?
Необходимость в создании унифицированного интерфейса. Практичного, и удобного.

Добавлено через 10 минут
Вот ещё один способ родил.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Test1
{
public: void Print(const char* text) { std::cout<<text; }
};
 
class Test2:public Test1
{
public: void Print(const Test2& rhs) { std::cout<<"text\n"; }
        using Test1::Print; //не хотелось бы писать эту директиву
                                   // для каждого имени метода, 
                                   //который скрыл наследник
                                   //может есть способ, который сразу на весь класс
                                   // эффект распространит?
};
 
int main()
{
    Test2 t;
    t.Print(t);     //можно
    t.Print("sdf"); //теперь можно
}
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
05.12.2011, 12:41     Наследование, и перегрузки методов #4
Цитата Сообщение от Bers Посмотреть сообщение
не хотелось бы писать эту директиву
Но придётся.
Определяя функцию с тем же именем, но другими аргументами, ты перекрываешь одноимённую функцию из базового класса. Поэтому приходится явно указывать компилятору "перенести" объявление из родительского класса в пространство имён дочернего.

Добавлено через 2 минуты
Цитата Сообщение от Bers Посмотреть сообщение
t.Print(t); //можно
Цитата Сообщение от Bers Посмотреть сообщение
Практичного, и удобного.
Как бы не о using'e беспокоиться надо... С какой стати объект печатает другой объект этого же класса? Это не архитектура, а набор бранных слов.
Bers
Заблокирован
05.12.2011, 17:11  [ТС]     Наследование, и перегрузки методов #5
Цитата Сообщение от Deviaphan Посмотреть сообщение
Как бы не о using'e беспокоиться надо... С какой стати объект печатает другой объект этого же класса? Это не архитектура, а набор бранных слов.
Мне нужно было как то проиллюстрировать проблему.
Если бы я привел реалистичную иллюстрацию, получилось бы "много букав".
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
05.12.2011, 18:11     Наследование, и перегрузки методов #6
оК, я просто намекнул.)
Yandex
Объявления
05.12.2011, 18:11     Наследование, и перегрузки методов
Ответ Создать тему
Опции темы

Текущее время: 03:58. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru