c ++ 11 — C ++ разделяет объект между двумя классами

Предположим, у меня есть два класса: FirstContainer а также SecondContainer
Они содержат одну и ту же ссылку (передают в своем конструкторе) на класс ThirdContainer,
FirstContainer и SecondContainer имеют следующие методы:
addMemberToThirdContainer
delMemberOfThirdContainer
getThirdContainerMembers

Когда ThirdContainer будет изменен, я хочу, чтобы два других обновились с помощью getThirdContainerMembers(), Для этого я использую образец наблюдателя / слушателя.

ThirdContainer имеет список слушателей и метод: addNewListener,
FirstContainer а также SecondContainer зарегистрироваться, выполнив: mThirdContainer.addNewListener(this);

Я не уверен, что это хороший способ сделать это, я новичок в ориентированном объекте.
Каковы мои другие возможности для достижения чего-то подобного?
Я не привязан ни к чему, что я сказал, просто здесь, потому что мне трудно объяснить, что я хочу сделать. Надеюсь это понятно.
Спасибо за помощь,
Лучший,

Редактировать:
Что бой с использованием предварительного объявления? Я мог бы сделать что-то вроде:

 class ParentContainer {
public:
ParentContainer(ThirdContainer&)
: mFirstContainer(*this), mSecondContainer(*this) { };

~ParentContainer();

void addMemberToThirdContainer() {
mThirdContainer.addMember();
notify();
};

void delMemberOfThirdContainer() {
mThirdContainer.delMember();
notify();
};

private:
std::vec<int>& getMemberOfThirdContainer() {
return mThirdContainer.getMember();
};

void notify() {
auto vec = getMemberOfThirdContainer();
mFirstContainer.update(vec);
mSecondContainer.update(vec);
};

ThirdContainer& mThirdContainer;
FirstContainer  mFirstContainer;
SecondContainer mSecondContainer;
};

Тогда в FirstContainer и SecondContainer что-то вроде:

 class ParentContainer;

class FirstContainer {
public:
FirstContainer(ParentContainer&);
~FirstContainer();

void update(std::vector<int>& vec);

private:
ParentContainer& mParentContainer;
};

В FirstContainer и SecondContainer я получу доступ к ThirdContainer, выполнив:
mParentContainer.addMemberToThirdContainer и mParentContainer.DelMemberOfThirdContainer.
И я получу уведомление. Я имею в виду, я думаю ….

1

Решение

Если вам нравится использовать библиотеки, вы можете использовать любую библиотеку, которая предоставляет систему сигналов / слотов, например Boost или Qt.

Если вам не нравятся библиотеки, постарайтесь

  1. Создать интерфейс (в C ++, просто абстрактный класс с чисто виртуальным методом, onModified например:

    class ThirdContainerListener {
    public: virtual void onContainerModified() = 0;
    // Virtual: is to make it overridable
    //  = 0: is the C++ way to say "abstract",
    //         which means this function MUST be overridden.
    };
    
  2. Делать vector указателей на слушателей (чтобы быть в безопасности, попробуйте использовать умные указатели, такие как shared_ptr) {Это идет в ThirdContainer}

    vector<shared_ptr<ThirdContainerListener>> listeners;
    
  3. Make (также внутри ThirdContainer), функция, которая добавляет слушателя, вот так

    void addNewListener(shared_ptr<ThirdContainerListener> container) {
    listeners.push_back(container); // Adds the pointer to the listeners
    }
    
  4. Скройте свой настоящий контейнер, вот так

    private: vector<int> list;
    
  5. Сделайте приватную функцию, которая вызывает всех слушателей, которые будут использоваться ЛОКАЛЬНО

    private: void callAllListeners() {
    // Traverse through all the listeners
    for(shared_ptr<ThirdContainerListener> listener: listeners) {
    // Call each one's overridden function
    listener->onContainerModified();
    }
    }
    
  6. Выставьте функции, которые изменяют ваш контейнер, они вызывают все слушатели, вот так

    public: void addData(int d) {
    list.push_back(d);
    callAllListeners();
    }
    
    // Also you could make "removeDataByIndex", "addManyData", etc...
    
  7. использование shared_ptr<ThirdContainer> как в первом, так и во втором контейнере, чтобы гарантировать, что ваши классы не будут пропускать память или указывать ни на что (висящий указатель)

0

Другие решения

Когда ThirdContainer изменен, я хочу, чтобы два других обновились с помощью getThirdContainerMembers(),

Зачем? Это не имеет особого смысла для меня. Или, по крайней мере, я не понимаю вашу мотивацию. Почему два контейнера не могут получить членов, когда они им действительно нужны, а не один раз при каждом обновлении? Или еще лучше — зачем вообще получать копию участников, когда вы можете просто держать членов в ThirdContainer и повторять их там?

Теперь вы можете сказать: «Может быть, итератор становится недействительным во время такого доступа». Но это также проблема во время звонка getThirdContainerMembers(),

ThirdContainer имеет список слушателей и метод: addNewListener.

Мне не нравится этот подход, и я бы посоветовал вам подумать, действительно ли вы хотите им следовать.

Я считаю, что он более подходит для интерпретируемых языков, которые имеют объекты с динамической типизацией, к которым вы можете добавлять или удалять функциональные возможности на лету, или, по крайней мере, у них есть механизмы, предоставляемые интерпретатором / виртуальной машиной, для наблюдения и самоанализа. С такими языками ваш ThirdContainer не должен быть разработан заранее, чтобы поддержать слушателей.

С C ++, однако, вам придется навязать инкапсулированный дизайн ThirdContainer (или, по крайней мере, наследовать от существующего дизайна), чтобы он поддерживал слушателей). Но потом, в другой раз вам нужно будет прослушать какое-то другое событие, и вам снова нужно будет создать подкласс или изменить интерфейс ThirdContainer — нет, я бы предпочел нет.

Вместо этого рассмотрите возможность того, чтобы кто-либо добавил элементы к ThirdContainer нести ответственность также за обновление FirstContainer а также SecondContainer случаи, которые разделяют это; или вообще избегать обновлений.

0