简体   繁体   English

两类之间的C ++共享对象

[英]C++ sharing object between two class


Suppose I have two class: FirstContainer and SecondContainer 假设我有两个类: FirstContainerSecondContainer
They hold the same reference (pass in their constructor) to the class ThirdContainer . 它们具有对ThirdContainer类的相同引用(在其构造函数中传递)。
FirstContainer and SecondContainer have the following methods: FirstContainer和SecondContainer具有以下方法:
- addMemberToThirdContainer addMemberToThirdContainer
- delMemberOfThirdContainer delMemberOfThirdContainer
- getThirdContainerMembers getThirdContainerMembers

When the ThirdContainer is modified, I want the two others to update using getThirdContainerMembers() . 修改ThirdContainer后,我希望其他两个使用getThirdContainerMembers()进行更新。 For this purpose I use the observer/listener pattern . 为此,我使用观察者/侦听器模式

ThirdContainer has a list of listener and a method: addNewListener . ThirdContainer有一个侦听器列表和一个方法: addNewListener FirstContainer and SecondContainer register by doing: mThirdContainer.addNewListener(this); FirstContainerSecondContainer通过执行以下mThirdContainer.addNewListener(this);注册: mThirdContainer.addNewListener(this);

I'm not sure this is the good way to do this, I'm new to oriented object. 我不确定这是执行此操作的好方法,我是面向对象的新手。
What are my other possibilities to achieve something like that ? 实现这种目标的其他可能性是什么?
I'm not attached to anything I stated, it's just here because I have hard time to explain what I want to do. 我不喜欢我所说的任何东西,它只是在这里,因为我很难解释我想做什么。 I hope it's clear. 我希望这很清楚。 Thanks for the help, 谢谢您的帮助,
Best, 最好,

Edit: What a bout using forward declaration ? 编辑:什么是使用前向声明的回合? I could do something like: 我可以做类似的事情:

 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; 
 };

Then in FirstContainer and SecondContainer something like: 然后在FirstContainer和SecondContainer中类似:

 class ParentContainer;

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

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

 private:
      ParentContainer& mParentContainer;
 };

In FirstContainer and SecondContainer I will have access to ThirdContainer by doing: 在FirstContainer和SecondContainer中,我将通过执行以下操作来访问ThirdContainer:
mParentContainer.addMemberToThirdContainer and mParentContainer.DelMemberOfThirdContainer. mParentContainer.addMemberToThirdContainer和mParentContainer.DelMemberOfThirdContainer。
And I will get notification. 我会收到通知。 I mean I guess .... 我的意思是我猜....

If you like using libraries, you can use any library that provide Signal/Slot system, like Boost or Qt. 如果您喜欢使用库,则可以使用任何提供Signal / Slot系统的库,例如Boost或Qt。

If you don't like libraries, you should try to 如果您不喜欢图书馆,则应尝试

  1. Create an interface (in C++, just an abstract class with pure virtual method, onModified for example: 创建一个接口(在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. Make a vector of pointers to listeners (to be safe, try to use smart-pointers, like shared_ptr ) {This goes inside the ThirdContainer} 创建指向侦听器的指针vector (为安全起见,请尝试使用智能指针,例如shared_ptr ){这位于ThirdContainer内部}

     vector<shared_ptr<ThirdContainerListener>> listeners; 
  3. Make (also inside the ThirdContainer), a function that adds listener, like that Make(也在ThirdContainer中),一个添加侦听器的函数,像这样

     void addNewListener(shared_ptr<ThirdContainerListener> container) { listeners.push_back(container); // Adds the pointer to the listeners } 
  4. Hide your real container, like that 像这样隐藏您的真实容器

     private: vector<int> list; 
  5. Make a private function that calls all listeners, to be used LOCALLY 创建一个私有函数来调用所有侦听器,以在本地使用

     private: void callAllListeners() { // Traverse through all the listeners for(shared_ptr<ThirdContainerListener> listener: listeners) { // Call each one's overridden function listener->onContainerModified(); } } 
  6. Expose functions that modify your container, those call all listeners, like that 公开修改容器的函数,这些函数会调用所有侦听器,就像这样

     public: void addData(int d) { list.push_back(d); callAllListeners(); } // Also you could make "removeDataByIndex", "addManyData", etc... 
  7. Use shared_ptr<ThirdContainer> in both First and Second container, to ensure your classes wouldn't leak memory or point to nothing (dangling pointer) 在第一个和第二个容器中都使用shared_ptr<ThirdContainer> ,以确保您的类不会泄漏内存或指向任何内容(悬空指针)

When the ThirdContainer is modified, I want the two others to update using getThirdContainerMembers() . 修改ThirdContainer后,我希望其他两个使用getThirdContainerMembers()进行更新。

Why? 为什么? This does not really make much sense to me. 这对我来说真的没有多大意义。 Or at least - I don't understand your motivation. 或者至少-我不理解你的动机。 Why can't the two containers just get the members when they actually need them, rather than once on every update? 为什么这两个容器不能在真正需要它们时才获得成员,而不是在每次更新时都获得成员? Or better yet - why get a copy of the members at all, when you can possibly just keep the members in ThirdContainer and iterate them in there? 还是更好的-当您可以只将成员保留在ThirdContainer并在其中进行迭代时,为什么要完全获得成员的副本?

Now, you could say "Maybe the iterator gets invalidated during such access". 现在,您可以说“也许迭代器在这种访问期间会失效”。 But that's also an issue during the call to getThirdContainerMembers() . 但这在调用getThirdContainerMembers()过程中也是一个问题。

ThirdContainer has a list of listener and a method: addNewListener. ThirdContainer有一个侦听器列表和一个方法:addNewListener。

I don't like this approach, and would advise you to consider whether you really want to follow it. 我不喜欢这种方法,建议您考虑是否要遵循它。

I believe it is more fitting for interpreted languages, which have dynamically-typed objects, to which you can add or remove functionality on the fly, or at least they have interpreter/virtual-machine-provided mechanisms for observation and introspection. 我认为它更适合于具有动态类型对象的解释语言,您可以在其中动态添加或删除功能,或者至少它们具有解释器/虚拟机提供的观察和内省机制。 With such languages, your ThirdContainer doesn't have to be designed in advance to support listeners. 使用这种语言,您的ThirdContainer不必预先设计为支持侦听器。

With C++, however, you will have to impose on the encapsulated design of ThirdContainer (or at least - inherit from an existing design), so that it supports listeners). 但是,对于C ++,您将必须对ThirdContainer的封装设计(或至少-从现有设计继承),以使其支持侦听器。 But then, another time you would need to listen on some other event, and you'll again need to subclass or alter the interface of ThirdContainer - no, I'd rather not. 但是,下一次,您将需要侦听其他事件,并且再次需要ThirdContainer或更改ThirdContainer的接口-不,我宁愿不要。

Instead, consider having whoever adds elements to the ThirdContainer be responsible for also updating the FirstContainer and SecondContainer instances which share it; 相反,考虑让谁向ThirdContainer添加元素的ThirdContainer也负责更新共享它的FirstContainerSecondContainer实例; or avoiding updates altogether. 或完全避免更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM