2542 / 1201 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
1

Вызов виртуального метода при создании

02.03.2016, 20:20. Показов 593. Ответов 11
Метки нет (Все метки)

Добрый вечер,

библиотека навязала следующее поведение:

- объект создан и валиден, если выделена память, вызван конструктор и вызван virtual bool init()

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Foo : public SomeCore
{
private:
    Foo();
    bool init();
public:
    static Foo* create()
    {
        Foo* ptr = new Foo();
        if(ptr && ptr->init)
        {
            return ptr;
        }
        delete ptr;
        ptr = nullptr;
        return ptr;
    }
};
Для наследников Foo опять же надо писать create и т.д. и т.п.

Есть ли решение не создавать и описывать static create, а унаследовать class FooSpecial : public Foo и при Foo* ptr = new FooSpecial(); иметь валидный объект с вызванным "корректным" вирт методом init?


Разбирался с CRTP с help-классом Initerom на его основе - так надо сделать подмену создавая Foo создается явно не Foo, а Foo_init_version.
Другие юзверги этой либы пишут макросы CREATE_METHOD(Foo);

Так как решения пока не вижу - думаю писать и мне макрос, который принимает тип и переменное количество параметров, что принимает класс в конструкторе: CREATE_METHOD(Foo, const std::string& filename);
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.03.2016, 20:20
Ответы с готовыми решениями:

Вызов виртуального метода в конструкторе
Помню расматривался этот вопрос на форуме - хочу освежить память почему при вызове виртуального...

Вызов виртуального метода класса наследника из вектора
#include <iostream> #include <vector> using namespace std; class A { public: ...

Вызов виртуального метода базового класса из указателя производного
Допустим есть такой код: #include <iostream> class Base { public: virtual void f() {...

Почему при переопределении виртуального метода в производном классе выводится метод базового?
Всем добра! Помогите разобраться почему при переопределении виртуального метода в производном...

11
Эксперт С++
8410 / 4085 / 892
Регистрация: 15.11.2014
Сообщений: 9,176
02.03.2016, 21:44 2
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Другие юзверги этой либы пишут макросы CREATE_METHOD(Foo);
это - оптимальный способ порешать проблему.
0
2542 / 1201 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
02.03.2016, 21:47  [ТС] 3
Беда, я думал будут ништячковые перегрузки new, паттерны и трюки, а тут уже сдались на старте((((
0
Эксперт С++
8410 / 4085 / 892
Регистрация: 15.11.2014
Сообщений: 9,176
02.03.2016, 22:04 4
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
я думал будут ништячковые перегрузки new, паттерны и трюки, а тут уже сдались на старте((((
у вас init - приватный.
никакие лайф-хаки уже не сработают.

конечно, настоящие ценители высоко оценят "паблик-морозова", и компанию.
но в данном случае овчинка не стоит выделки.

проще попользовать простейший макрос,
и не заморачиваться.
1
Эксперт С++
4974 / 3081 / 456
Регистрация: 10.11.2010
Сообщений: 11,160
Записей в блоге: 10
02.03.2016, 22:22 5
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
castaway, было бы круче если я выложил сюда тонну листинга кода, как другие участники форума?
Вы меня не поняли. Я не это имел ввиду.

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
И если вопрос не понятный - укажите, где именно - уточню. Как по мне понятно всё.
Я не так силён в С++, но мне непонятен сам вопрос в целом. Да и почему-то мне кажется что в 10-й строке ошибка.

Вы не подумайте что я хочу придраться. Просто это не первый ваш вопрос который я не могу понять. Помниться..., мы уже ссорились из-за одного такого. Ссорится и ругаться я больше не хочу. Если можно - переобдумайте вопрос.

rikimaru2013, у всех (в том числе и у экспертов этого форума) есть свои недостатки при создании вопросов (тем). Бывало и я не мог правильно задать вопрос, и мне приходилось уточнять условие по ходу темы. Это нормально.
0
1489 / 783 / 172
Регистрация: 05.12.2015
Сообщений: 2,351
03.03.2016, 10:24 6
rikimaru2013, Я так и не понял, почему нельзя написать обертку, т.е. делать все эти вещи в конструкторе?
0
2542 / 1201 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
03.03.2016, 11:31  [ТС] 7
avgoor, так предложите конкретнее. Вызов вирт метода в конструкторе беда, а обёртку надо так же писать для каждого класса как и static create
0
1489 / 783 / 172
Регистрация: 05.12.2015
Сообщений: 2,351
03.03.2016, 11:50 8
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
обёртку надо так же писать для каждого класса как и static create
Как я понял, в библиотеке есть иерархия классов, которую вы хотите отразить на свою?
Тогда не надо наследоваться от библиотечных классов. Вы получите в своем родительском классе не тот родительский библиотечный, от которого унаследован потомок в библиотеке, и виртуальное наследование здесь не поможет.
Можно, например, в своей иерархии хранить ссылку на библиотечный класс.

Добавлено через 7 минут
Маейрс, говорил, что те, кто пишет такие интерфейсы библиотек - уимблдоны, и турнир библиотека у них уимблдонская.
0
2542 / 1201 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
03.03.2016, 11:55  [ТС] 9
avgoor, и так как композитная связь надо описать весь интерфейс вручную.

Добавлено через 1 минуту
avgoor, ссылку на цитату про турнир уимблдона

Добавлено через 2 минуты

Не по теме:

castaway, пока, что с тех кто понял вопрос и нет : счёт 1 нет / 2 да. Интрига кто же победит)

0
1489 / 783 / 172
Регистрация: 05.12.2015
Сообщений: 2,351
03.03.2016, 12:00 10
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
и так как композитная связь надо описать весь интерфейс вручную.
Да, потому, что в Библиотеке иерархия : Base->Derived->Derived2, а У вас, допустим, MyBase->OtherClass->AbsolutelyOtherClass.
Можно, конечно, завязать именования из библиотеки и свои и завернуть все в макросы, но в любом случае интерфейс с init лучше обернуть в конструктор, следуя RAII.

Добавлено через 2 минуты
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
ссылку на цитату про турнир уимблдона
То мой вольный перевод был.

Добавлено через 2 минуты

Не по теме:

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
счёт 1 нет / 2 да. Интрига кто же победит
Я тоже сперва ни хрена не понял, так что 1.5/1.5

0
1378 / 405 / 144
Регистрация: 22.10.2014
Сообщений: 872
04.03.2016, 01:03 11
rikimaru2013, Пальцем в небо, т.е. я тоже паршиво понял задачу, но вдруг вы следующее хотели
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <utility>
 
template<typename T, typename ... Args>
class MagicWrapper
{
    T* ptr_;
public:
    MagicWrapper(Args&& ... args)
            : ptr_(new T(std::forward<Args...>(args)...))
    {
        ptr_->init();
    }
 
    operator T*()
    {
        return ptr_;
    }
};
 
template<typename T, typename ... Args>
class MagicWrapper2: public T
{
public:
    MagicWrapper2(Args&& ... args)
            : T(std::forward<Args...>(args)...)
    {
        T::init();
    }
};
 
struct SomeCore
{
    virtual ~SomeCore()
    {
    }
 
    virtual bool init()
    {
        return true;
    }
 
    template<typename T, typename ... Args>
    static T* create(Args&& ... args)
    {
        T* ptr = new T(std::forward<Args...>(args)...);
        if (ptr && ptr->init())
        {
            return ptr;
        }
        delete ptr;
        ptr = nullptr;
        return ptr;
    }
};
 
class Foo: public SomeCore
{
public:
    bool init()
    {
        return false;
    }
 
    Foo(int bla)
    {
        (void)bla;
    }
};
 
int main()
{
    // Тут очень тоскливо перечислять типы аргументов, и также нужно следить за удалением самого враппера.
    Foo* f1 = MagicWrapper<Foo, int>(10);
    // Тут тоже тоскливо перечислть
    Foo* f2 = new MagicWrapper2<Foo, int>(10);
    // Так что давайте просто попросим копилятор сгенерить для нас нужный create :)
    Foo* f3 = SomeCore::create<Foo>(10);
}
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
04.03.2016, 13:10 12

Не по теме:

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
"Да, в мире существует множество языков программирования, но зачем себя ограничивать, если есть С++?"
А как насчет "Да, в мире существует С++, но зачем себя им ограничивать?"



Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Беда, я думал будут ништячковые перегрузки new, паттерны и трюки, а тут уже сдались на старте((((
Может еще рекурсивных полиморфных перегруженных лямбд или свободных монад с линзами отсыпать? На кой все переусложнять?

The life of rikimaru2013:
2
Миниатюры
Вызов виртуального метода при создании  
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.03.2016, 13:10

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Преобразование типа при вызове виртуального метода через указатель на базовый класс
Доброго времени суток. Наткнулся на вот такой вопрос в сети и пока что не смог на него ответить,...

Непонятный вызов Деструкторов при создании списка
Непонятный вызов Деструкторов при создании списка. #include &lt;iostream&gt; #include &lt;list&gt;...

Переопределение виртуального метода
Нужно написать виртуальный метод в родительском классе , который находит площадь круга. Затем...

ООП в C++: Вызов родительского конструктора с параметром при создании объекта дочернего класса
Здравствуйте! Столкнулся с такой проблемой: если есть родительский класс с конструктором, то при...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.