开发者

Is it bad practice to use co-dependent classes?

If I have a Container class which holds a bunch of Component objects (similar to Java's UI framework), would it be poor style/practice to keep track of the Container parent within each Component?

This ends up causing some strange compiler issues because the Component includes the header file for Container and vice-versa. Even with a header guard fix, I end up having to declare a prototype class Component; on top of the Container header, and similarly for Component.

It seems like you have to go through quite a bit of trouble to get a two-way interaction between two classes. Would it be advisable to look for another solution to the problem that co-dependency "solves" or is this convoluted implementation expected from C++ and I should just suck it up?

EDIT:开发者_如何学编程 Perhaps some context/reasoning would help. The reason I'm using this co-dependency is because I need to notify the parent when a child's destructor has been called (so it can be removed from the list of children), and I also need to have the drawn position of the child be relative to that of the parent.

Thanks,

Jengerer


Having a component keep a pointer to its parent is widely used, and I don't see it as bad practice. It can be used for a variety of things, from working up trees of widgets to handling lost or leaked components.

To work around the issue with the compiler, you'll need to either put the include lines inside header guards, or have a third file with forward declarations for both classes (in the appropriate namespace).

I've seen the latter done in a few large OO libraries, and it is usually then included by almost every other file in the project. While that can lead to a bit of namespace pollution, it has some benefits (not needing to include the full class definition or dependencies of another class just to have a pointer to it).

Widget.hpp:

#include "Library.hpp"

namespace MyLibrary
{
    class Widget
    {
    private:
        Window * parent;
    };
}

Window.hpp:

#include "Library.hpp"

namespace MyLibrary
{
    class Window
    {
    private:
        std::vector<Widget*> widgets;
    };
}

Library.hpp:

namespace MyLibrary
{
    class Window;
    class Widget;
}


Actually I think it's a design problem. You really should look at the design as a whole and see if you can design it better. Ask yourself why you have the dependent classes requiring access to the container. Perhaps the container is providing functionality it should not. Can this functionality be provided in another way?


It's generally better not to have such cyclic dependencies: they're a bit of a pain to code, frustrate logical reasoning about the code, testability etc..

They can be avoided easily anyway - you could keep some functors in the Components, then point them at the Container operations appropriate to the events being handled, or derive the Container from an abstract interface, so the Components can have a pointer to it and the Container derive therefrom. Or the Components may be stored by (smart) pointer, with a derived type implementing virtual event handlers customised for the container. There are lots of other possibilities e.g. if you want to avoid run-time overhead, consider CRTP or template policy classes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜