Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как перегрузить методы без виртуалок / 13 сообщений из 13, страница 1 из 1
21.10.2012, 17:06
    #38007335
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
#include <iostream>
using namespace std;

class first
{
    public: first() { myName(); }
    void myName() { cout << "first" << endl; }
};

class later : public first
{
    public: later() : first() { }
    void myName() { cout << "later" << endl; }
};

int main()
{
    first(); later();
    return 0;
}



как отнаследовать later, чтобы first вызвал myName из later, а то этот пример в обоих случаях вызывает first::myName()
...
Рейтинг: 0 / 0
21.10.2012, 17:20
    #38007343
Sheraton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
В сначала вызывается конструктор базового класса, потом уже производного.
Таким образом, у вас по любому будет вызываться first::myName() потому, что он в конструкторе базового класса.
Что бы переопределить myName() производном классе нужно, что то типа:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
#include <iostream>
using namespace std;

class first
{
    public: 
    first() {  }
    void myName() { cout << "first" << endl; }
};

class later : public first
{
    public: 
    later() : first() { }
    void myName() { cout << "later" << endl; }
};

int main()
{
    first().myName(); 
    later().myName();
    return 0;
}
...
Рейтинг: 0 / 0
21.10.2012, 17:49
    #38007358
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
Sheraton,

просто есть контрол, которому хочется заменить пару методов, подменяющих источник данных и чтобы все остальное у него работало как и работает сейчас. А точки клиентского кода, где юзается интерфейс этого контрола мне трогать не хочется...
...
Рейтинг: 0 / 0
21.10.2012, 18:14
    #38007379
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
Lumixкак отнаследовать later, чтобы first вызвал myName из later, а то этот пример в обоих случаях вызывает first::myName()
Вы очевидно не понимаете, что внутри конструктора first() { ... } его наследник, объект later еще не сконструирован, и в его полях находятся случайные значения. Поэтому вызов любого его метода - это выстрел в ногу.

Который вы при желании естественно можете сделать:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
template <class child>
class first
{
    public: first() { static_cast<child*>(this)->myName();  }
};

class later : public first<later>
{
    public: later() : first() { }
    void myName() { cout << "later" << endl; }
};

int main()
{
    first();  // не будет работать, делайте отдельное инстанцирование шаблона по аналогии с later
    later();
    return 0;
}



Помните, что к полям later в методе later::myName (и вызываемых из него) нельзя обращаться, также как и к полям других базовых классов указанных после first в списке предков later.

В общем, я рекомендую никогда так не делать, потому что проверять вместо компилятора такие ограничения с ростом проекта будет все сложнее и рано или поздно (скорее рано) отстрел ноги таки произойдет.
...
Рейтинг: 0 / 0
21.10.2012, 18:19
    #38007388
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
Lumixпросто есть контрол, которому хочется заменить пару методов, подменяющих источник данных и чтобы все остальное у него работало как и работает сейчас. А точки клиентского кода, где юзается интерфейс этого контрола мне трогать не хочется...
Сделайте не наследование, а агрегацию (делегирование).
Т.е. создайте новый класс, в котором будет одно поле - экземпляр старого класса.
В новом классе объявите все методы из старого класса, в которых просто вызовите одноименные методы поля.
Ну кроме тех которые вы хотите переопределить.
...
Рейтинг: 0 / 0
21.10.2012, 18:25
    #38007395
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
Хотя конечно, если из конструктора старого класса уже вызывается некий его метод, то не модифицируя этот класс вы никак не переопределите этот метод, если он невиртуальный.
...
Рейтинг: 0 / 0
21.10.2012, 19:09
    #38007433
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
Anatoly MoskovskyХотя конечно, если из конструктора старого класса уже вызывается некий его метод, то не модифицируя этот класс вы никак не переопределите этот метод, если он невиртуальный.

ок, понятно
сэкономить не получится
что-нибудь замутим как обычно...
...
Рейтинг: 0 / 0
21.10.2012, 21:27
    #38007508
Quartz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
Anatoly MoskovskyХотя конечно, если из конструктора старого класса уже вызывается некий его метод, то не модифицируя этот класс вы никак не переопределите этот метод, если он невиртуальный.
Подскажите, каким же образом переопределить виртуальный метод, вызываемый из конструктора базового класса?
...
Рейтинг: 0 / 0
21.10.2012, 21:40
    #38007513
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
QuartzAnatoly MoskovskyХотя конечно, если из конструктора старого класса уже вызывается некий его метод, то не модифицируя этот класс вы никак не переопределите этот метод, если он невиртуальный.
Подскажите, каким же образом переопределить виртуальный метод, вызываемый из конструктора базового класса?
Ну я неточно выразился. В одну фразу впихнул две.
Виртуальный переопределить можно, но из конструктора его вызвать нельзя.
...
Рейтинг: 0 / 0
22.10.2012, 21:13
    #38008860
Mozok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
Anatoly Moskovsky,

ну если уж совсем точно:
ISO/IEC 14882 12.7.4When a virtual function is called directly or indirectly from a constructor or from a destructor, including
during the construction or destruction of the class’s non-static data members, and the object to which the
call applies is the object (call it x) under construction or destruction, the function called is the final overrider
in the constructor’s or destructor’s class and not one overriding it in a more-derived class.
...
Рейтинг: 0 / 0
23.10.2012, 00:04
    #38009021
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
Mozokну если уж совсем точно:...самый лёгкий способ получить pure virtual function call
...
Рейтинг: 0 / 0
23.10.2012, 01:21
    #38009063
Abstraction
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
egorychMozokну если уж совсем точно:...самый лёгкий способ получить pure virtual function call А компилятор пропустит? MSVC 2010 ругается LNK2001: unresolved external.
...
Рейтинг: 0 / 0
23.10.2012, 02:02
    #38009077
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как перегрузить методы без виртуалок
Abstraction,

Попробуйте так 9841953
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как перегрузить методы без виртуалок / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]