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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
babkaVkedah
Заблокирован
#1

Можно ли из класса родителя просигналить всем потомкам? - C++

11.07.2013, 10:18. Просмотров 651. Ответов 12
Метки нет (Все метки)

Если есть базовый класс "X" и несколько его потомков "A", "B" и "C", можно ли как то через объект базового класса сообщить всем созданным потомкам выполнить какую - то функцию?

Например:
C++
1
2
3
4
5
6
7
8
9
10
X* x = new X;
A* a = new A;
B* b = new B;
C* c = new C;
 
//хочу как - то вызвать функцию, виртуальную наверно, 
//в классе "X", чтоб она вызвалась во всех потомках
 
x->DoWork();
//и после этого во всех классах потомках должна вызваться такая же функция
... ???
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.07.2013, 10:18
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Можно ли из класса родителя просигналить всем потомкам? (C++):

Правда, что указатель класса-наследника не может указывать на объект класса-родителя? - C++
Доброго времени суток! Пример кода ниже. Правда ли , что указатель класса-наследника не может указывать на объект класса-родителя? ...

Инициализация членов дочернего класса членами класса родителя - C++
Есть уже созданный класс-родитель A. Как эффективно инициализировать дочерний класс B членами класса A?

Бинарное дерево подклассов основного класса-узла. Доступ к подклассам по указателю - объекту класса-родителя - C++
Короче, необходимо сделать бинарное дерево, решающее арифметическое выражение, предварительно туда записанное. Есть основной класс...

Задачка для новичков #2: вывести в методе класса-родителя значение данных-членов из дочернего класса - C++
Вдохновленный соседней темой тоже решил задать свой вопрос таким же начинающим программистам как и я :) Все кто хочет попробовать дать...

Переопределение переменной класса-родителя - C++
Есть базовый класс button_c и производный от него about_c. В about_c я попытался переопределить значения переменных w, h, dir, dir_h, но...

Создание категорий меню в private класса родителя - C++
Подскажите пожалуйста как можно занести в private класса родителя 7 этих категорий: class Menu{ private: static...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
ForEveR
В астрале
Эксперт С++
7971 / 4733 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
11.07.2013, 10:22 #2
babkaVkedah, Возможно. Сохранять все инстансы в базовом классе. Но это откровенно говоря изврат.
Ilot
Модератор
Эксперт С++
1809 / 1166 / 227
Регистрация: 16.05.2013
Сообщений: 3,074
Записей в блоге: 5
Завершенные тесты: 1
11.07.2013, 10:35 #3
babkaVkedah, не думаю, что это возможно по причине того что будет необходимо выполнить метод для всех наследников класса. А теперь вопрос: существеут ли в С++ способ/метод по умолчанию учета всех созданных объектов класса A, B, C? Насколько мне известно нет. Поля класса инициализируются при определении объектов и связи с базовым классом в последствии не несут. Что бы вызвать выполнение методов наследников базового класса необходимо ссылыться на каждый созданный объкт. Ну... примерно так.

Единственный вариант который мне приходит на ум это создание в базовом классе массива указателей на создаваемые объекты. Таким образом создавая новый объект вы автоматически сохраняете на него ссылку. Далее при вызове вашего метода он(метод) считывает адрес созданных объектов и вызывает их методы. Все это происходит в цикле по всему массиву указателей до встречи нулевого указателя. Как это реализовать это отдельный вопрос, но думаю суть ясна. Чем-то напоминат списки.
babkaVkedah
Заблокирован
11.07.2013, 10:53  [ТС] #4
У меня есть ещё вариант, задействовать Qt.
В базовом, да и во всех остальных, создать два метода Get и Set (set - signal, get - slot), чтоб можно было бы передавать что - то, например через строку джейсоновской натацией и получать что - то. Во всех классах потомках вызывать два connect, присоединяя Set потомка к Get родителя. А в базовом классе в слоте Get делать emit Set, чтоб при каждом получение Get из любого потомка, он испускал сигнал ко всем потомкам, ну как - то так
nxtech
77 / 59 / 2
Регистрация: 26.06.2013
Сообщений: 198
11.07.2013, 13:58 #5
Примитивный вариант
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <iostream>
#include <string>
#include <vector>
 
class Base
{
public:
    static void Signal()
    {
        for (std::vector<Base*>::iterator it = _instances.begin() ; it != _instances.end(); ++it)
        {
            (*it)->DoWork();
        }
    }
 
    virtual ~Base()
    {
        for (std::vector<Base*>::iterator it = _instances.begin() ; it != _instances.end(); ++it)
        {
            if (*it == this)
            {
                _instances.erase(it);
                break;
            }
        }
 
        std::cerr << "Calling method \'" << __FUNCTION__ << "\' for object \'" << _name << "\'\n";
    }
    Base(std::string const& name)
    {
        _name = name;
        _instances.push_back(this);
 
        std::cerr << "Calling method \'" << __FUNCTION__ << "\' for object \'" << _name << "\'\n";
    }
    virtual void DoWork()
    {
        std::cerr << "Calling method \'" << __FUNCTION__ << "\' for object \'" << _name << "\'\n";
    }
 
private:
    static std::vector<Base*> _instances;
 
protected:
    std::string _name;
};
std::vector<Base*> Base::_instances;
 
class DerivedA : public Base
{
public:
    virtual ~DerivedA()
    {
        std::cerr << "Calling method \'" << __FUNCTION__ << "\' for object \'" << _name << "\'\n";
    }
    DerivedA(std::string name) : Base(name)
    {
        std::cerr << "Calling method \'" << __FUNCTION__ << "\' for object \'" << _name << "\'\n";
    }
    void DoWork()
    {
        std::cerr << "Calling method \'" << __FUNCTION__ << "\' for object \'" << _name << "\'\n";
    }
};
 
class Derived2A : public DerivedA
{
public:
    virtual ~Derived2A()
    {
        std::cerr << "Calling method \'" << __FUNCTION__ << "\' for object \'" << _name << "\'\n";
    }
    Derived2A(std::string name) : DerivedA(name)
    {
        std::cerr << "Calling method \'" << __FUNCTION__ << "\' for object \'" << _name << "\'\n";
    }
    void DoWork()
    {
        std::cerr << "Calling method \'" << __FUNCTION__ << "\' for object \'" << _name << "\'\n";
    }
};
 
int main()
{
    Base* base = new Base("base");
    DerivedA derivedA("derivedA");
    DerivedA* derived2A = new Derived2A("deriveda2A");
 
    Base::Signal();
 
    delete derived2A;
    delete base;
    return 0;
}
Кудаив
329 / 406 / 24
Регистрация: 27.05.2012
Сообщений: 1,168
Завершенные тесты: 2
11.07.2013, 19:50 #6
паттерн проектирования "наблюдатель", не?
на Qt куда элегантнее будет
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
12.07.2013, 05:03 #7
Цитата Сообщение от babkaVkedah Посмотреть сообщение
x->DoWork();
//и после этого во всех классах потомках должна вызваться такая же функция
Что мешает в этом месте вызвать эти функции?
nxtech
77 / 59 / 2
Регистрация: 26.06.2013
Сообщений: 198
12.07.2013, 07:04 #8
Цитата Сообщение от Кудаив Посмотреть сообщение
паттерн проектирования "наблюдатель", не?
В общем, да.
Цитата Сообщение от Кудаив Посмотреть сообщение
на Qt куда элегантнее будет
Не знаком, не знаю.
Цитата Сообщение от alsav22 Посмотреть сообщение
Что мешает в этом месте вызвать эти функции?
Наверное то, что не ведется yчет всех объектов-потомков.
babkaVkedah
Заблокирован
12.07.2013, 08:14  [ТС] #9
Цитата Сообщение от nxtech Посмотреть сообщение
Наверное то, что не ведется yчет всех объектов-потомков.
Конечно не ведётся, иначе какая же это автоматизация Думаю, лучший вариант - тот, который я сам предложил через Qt
nxtech
77 / 59 / 2
Регистрация: 26.06.2013
Сообщений: 198
12.07.2013, 09:32 #10
Ну, если Qt позволяет меньше писать кода, то, можно этим воспользоваться.
Но учет все-равно должен как-то где-то вестись, пусть это и скрыто от нас (connect как бы намекает).
babkaVkedah
Заблокирован
12.07.2013, 10:19  [ТС] #11
Цитата Сообщение от nxtech Посмотреть сообщение
Но учет все-равно должен как-то где-то вестись, пусть это и скрыто от нас
В том то и дело, что не надо
Фишка в том, что как я и говорил, в базовом классе делаешь SET и GET, а коннектишся к ним только в дочерних классах. Тоесть в дочернем классе надо просто иметь указатель на базовый и делать два коннекта.
Кстате, как лучше получить указатель на базовый класс в дочерних?
Как известно this, возвращает указатель на данный класс, может есть какая - то конструкция для получения указателя родителя? Может он так же как и для this где - то не явно храниться? Или же надо в базовом классе передавать указатель на самого себя в конструкторе?
nxtech
77 / 59 / 2
Регистрация: 26.06.2013
Сообщений: 198
12.07.2013, 10:59 #12
Цитата Сообщение от babkaVkedah Посмотреть сообщение
В том то и дело, что не надо
Ну, может я не совсем понятно и корректно выражаюсь. Но вот понятно, что объект генерирующий сигнал, не обязан ничего знать о получателях сигнала (более того, получателей может и не быть вовсе) и, соответственно, получатели не обязаны ничего знать об объекте генерирующем сигнал.
Но сама внутренняя реализация механизма сигналов-слотов должна же как-то знать какие адреса (функции) вызывать при поступлении сигнала.
soican
49 / 23 / 1
Регистрация: 16.11.2011
Сообщений: 329
Записей в блоге: 5
12.07.2013, 22:10 #13
nxtech, кладу в избранное, как пособие по наследованию)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.07.2013, 22:10
Привет! Вот еще темы с ответами:

Нужно из класса наследника передать параметры в класс родителя - C++
#include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;math.h&gt; class ploskost{ protected: float d; int x1,y1,x2,y2; public: ...

Изменения названия переменной класса родителя в классе наследнике - C++
Изменения названия переменной класса родителя в классе наследнике Возможно ли это, если да то как? Например class Object { ...

Лишнее удаление родителя при создании класса наследника - C++
Не могу понять откуда в выводе программы появляется первая надпись &quot;delete A&quot;. По идее надписей &quot;delete&quot; должно быть столько же, сколько и...

Как избежать повтора параметров конструктора класса-родителя в конструкторе наследника? - C++
С каждым новым наследуемом классом, число параметров конструктора увеличивается. class A { public: A(int a, float b, double c) ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
12.07.2013, 22:10
Ответ Создать тему
Опции темы

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