Лучший способ вызвать функцию в классе из объекта в этом классе - PullRequest
0 голосов
/ 27 июня 2018

Хорошо, извините, если это глупый вопрос. Допустим, у меня есть класс, и я хочу вызвать функцию из этого класса, используя объект внутри этого класса, чтобы что-то изменить в классе. Например:

class Foo;
class Bar{
public:
    Bar(Foo *parent): parent(parent) {}
    void barClickEvent(){
        parent->changeSomething(10);
    }
private:
    Foo * parent;
};

class Foo {
public:
    Foo():bar(this), something(5) {}
    void changeSomething(int x){something = x;}
private:
    Bar bar;
    int something;
};

Я создаю объект типа Foo (который автоматически создает объект типа Bar). Чтобы все Bar имели доступ к функциям в Foo, я передаю указатель на Bar, указывающий на Foo (его родитель). Это самый эффективный способ сделать это?

Причина, по которой я спрашиваю это, заключается в том, что я внедряю нечто подобное для графического интерфейса некоторых программ, например, я могу нажать кнопку на боковой панели, которая, в свою очередь, меняет цвет родительского элемента (основной окно). В этом случае это может быть не так уж и плохо, но как насчет того, когда я хочу изменить всю тему пользовательского интерфейса, и мне нужно вызывать функции во многих объектах от многих родителей. Мне понадобится много указателей, и это может стать немного грязным.

Какие-нибудь предложения о том, как лучше решить такую ​​проблему, как эта?

Спасибо

1 Ответ

0 голосов
/ 27 июня 2018

Наиболее подходящий способ сделать это - использовать шаблон наблюдателя . Идея состоит в том, чтобы передать функциональный объект источнику события. Это гарантирует, что вы сможете установить любое действие для события без указания источника события.

Самый простой способ реализовать это в C ++ - использовать класс std::function. Например:

#include <functional>

class Bar {
public:
    using OnClicked = std::function<void(int)>;

    void onClicked(OnClicked callback) {
        m_OnClicked = std::move(callback);
    }
    void barClickEvent() {
        if (m_OnClicked)
            m_OnClicked(10);
    }
private:
    OnClicked m_OnClicked;
};

class Foo {
public:
    Foo() : something(5) {
        bar.onClicked([this](int value) {
            changeSomething(value);
        });
    }
    void changeSomething(int x){something = x;}
private:
    Bar bar;
    int something;
};

Как вы можете видеть, Bar ничего не знает о Foo, который обеспечивает слабую связь ваших компонентов, и теперь вы можете заставить каждый экземпляр Bar делать совершенно разные вещи, когда происходит событие .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...