[英]C++ sharing object between two class
Suppose I have two class: FirstContainer
and SecondContainer
假设我有两个类:
FirstContainer
和SecondContainer
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);
FirstContainer
和SecondContainer
通过执行以下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 如果您不喜欢图书馆,则应尝试
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. };
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;
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 }
Hide your real container, like that 像这样隐藏您的真实容器
private: vector<int> list;
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(); } }
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...
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 usinggetThirdContainerMembers()
.修改
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
也负责更新共享它的FirstContainer
和SecondContainer
实例; or avoiding updates altogether. 或完全避免更新。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.