包含类如何调用包含类的成员函数 - C++ 中的组合
这是从 C++ 角度来看的一般设计问题。我有一个容器类,其中包含其他两个类的对象。
从容器类中,我们可以调用所包含的类对象的方法,“因为我们拥有所包含的类对象的句柄”,例如 objContainedClass1->SomeMthod();
但我想知道包含的类对象(objContainedClass1)如何访问容器类的方法。
我可以想到以下方法:
容器类对象将指向其自身的指针(this 指针)传递给所包含的类构造函数。使用此指针,包含的类可以访问容器类的方法。
将容器类中的某些函数设为静态。
还有更多实现这一目标的想法吗?
谢谢
This is a general design question from C++ perspective. I have a container class which contains objects of 2 other classes.
From container class we can call methods of the contained class object "as we have handle to the contained class object" e.g. objContainedClass1->SomeMthod();
But I want to know how would the contained class object (objContainedClass1) access methods of container class.
I can think of following ways:
The container class object passes the pointer to itself (this pointer) to the contained class constructor. Using this pointer, the contained class can access the methods of container class.
Make some functions in the container class as static.
Any more ideas of achieving this?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不要这样做,通常,对于一个类来说,必须了解其容器是一个糟糕的设计。通常这意味着你打破了单一责任原则。
Don't, typically it is bad design for a class to have to know about its container. Usually it means you have broken the single responsibility principle.
两种方式都可以用于不同的目的。如果您只需要调用静态方法,#2 就可以了。但如果需要访问容器类的实例方法,则需要有容器类指针,所以#1就是方法。
如果您需要通用解决方案,请实现观察者模式。在这种情况下,包含的类对容器一无所知,它只是在必要时引发事件。
Both ways are OK for different purposes. If all you need is to call static methods, #2 is OK. But if you need to access instance methods of container class, you need to have container class pointer, so #1 is the way.
In the case you need generic solution, implement observer pattern. In this case contained class doesn't know anything about container, it just raises events when necessary.
有许多更糟糕的选择。
如果包含的类不在容器类外部使用,则可以将它们作为容器类的一部分。
您可以使容器成为所包含类的朋友(恶心)。
您可以将引用或 boost::shared_ptr 传递给容器,而不是原始指针。最好的方法取决于每个方法的寿命。如果可以的话,避免使用原始指针。
我实际上想做的是隔离所包含的对象需要使用的容器方法的接口(例如,IContainerCallback),并将其用作两者之间的链接。因此,所包含的对象仅通过与容器的实现解耦的接口类间接引用容器。
There are a number of bad-to-worse options.
You could make the contained classes part of the container class, if they are not used outside it.
You could make the container a friend of the contained classes (yuck).
You could pass in a reference or boost::shared_ptr to the container instead of a raw pointer. The best method depends on the lifetimes of each. Avoid raw pointers if you can.
What I would actually try to do is to isolate the interface of the container methods that the contained objects need to use (
IContainerCallback
, say), and use that as the link between the two. So the contained objects reference the container only indirectly, via an interface class that is decoupled from the implementation of the container.这就是所谓的“再见 OOP!”选项,我尽可能避免使用它。
如果包含类实现一个接口并且包含的类只知道该接口,我个人认为没有任何问题。事实上我自己就是这么做的。显然,人们必须意识到该方法的陷阱,例如,当所包含的对象在容器销毁期间(或容器处于中间状态的任何其他时刻)调用容器的方法时。
为了进一步将包含类与包含类解耦,还可以使用事件或消息。被包含的对象不知道它们被包含在哪里,而是发送消息。包含对象在创建包含对象时将其自身注册为来自它们的消息的接收者。该技术允许使对象真正独立,但需要 (1) 一些消息传递框架,(2) 由于 C++ 的静态特性,实现起来相当复杂,(3) 还需要额外级别的文档,因为类的接口现在包括消息传递。
否则,请三思为什么包含的对象需要调用容器的方法。您是否需要将容器的一些通用功能拆分为第三类?如果所包含的对象确实是活动对象并且是系统中事件的逻辑源,那么您可能确实需要一些基本的事件/消息系统来允许容器有效地轮询/监视所包含对象中的状态更改。
That's what can be called "goodbye OOP!" option and I refrain from using it as much as possible.
Provided that the containing class implements an interface and contained classes know only the interface, I personally do not see any problem. In fact that is what I do myself. Obviously one has to be aware of the approach's gotchas, when e.g. contained object calls container's method during destruction of the latter (or any other moment of time when the container is in an intermediate state).
To further decouple the contained from the containing classes, events or messages could be used too. Contained objects do not know where they are contained, but instead send messages. Containing object when creating the contained objects registers itself as the recipient of the messages from them. That technique allows to make the objects literally independent, but requires (1) some messaging framework, (2) due to static nature of C++ rather elaborate to implement and (3) also needs additional level of documentation as interface of classes now includes messaging.
Otherwise, think twice why contained objects need to call container's methods. Could it be that you need to split off the container some generic functionality into 3rd class? If the contained objects are indeed the active objects and are the logical source of events in the system, then you might really need some basic event/messaging system to allow the container to efficiently poll for/monitor state changes in the contained objects.
不。容器类的职责是包含东西,没有别的。如果您需要容器类根据其中包含的内容采取操作,请让第三个对象执行这些操作。例如,我假设您正在根据类的内容重新排列或以其他方式修改类的集合。不要尝试在包含的类中执行此操作,而是在使用容器作为依赖项的类中执行此操作。
Don't. The responsibility of a container class is to contain things, nothing else. If you need your container class to take actions based on what's contained within, have a third object perform those actions. For instance, I'm assuming that you're rearranging or otherwise modifying the collection of classes based on the contents of the classes. Instead of attempting to do so within the contained classes, perform this action in a class which uses the container as a dependency.