开发者

Compatibility of classes with distinct owners

Given:

class Foo1 { 
 public:
  typedef Foo2 owner;
};
class Foo2 {
 public:
  typedef Foo1 vassal;
  typedef Foo3 owner;
};
//... and so on 
class FooN {
 public:
  typedef FooNm1 vassal;
  typedef ExternalType owner;  // problem
  owner* owner();
};

Question:

How to associate class hierarchy with external owner, preserving compatibility between classes of distinct owners.

Problems:

  1. If we make FooN a template with owner as a template parameter, then every class of the Foo{N} hierarchy will be infected by this owner via dependency chain.
  2. If we make an interface FooNOwner for external owner to inherit from, then we face need of dynamic casting to move from algorithms on the Foo{N} hierarchy to an actual owner.

Is there a design pattern to solve my problem?

Example of a situation where these problems arise: You have a structure that consists of Foo{N} classes. It is used for fast searching and a query from it returns list of Foo{N} objects. I want to get a pointer of concrete type ExternalOwner* to an external owner from a returned FooN object, so avoiding dynamic casting. At the same time I want to operate with Foo{N}(maybe without FooN) objects with distinct FooN::owner without looking back on this difference.

Update:

Maybe the only valid way to do this is to define common Owner interface and to overload it by owners for usage in the context where different owner classes take place. This interface thereby is defined by a context of its usage (but FooN has nothing to do with the context of FooN::owner usage). This is the problem I was trying to solve initially - separate different tasks, this approach does not help me.

My solution

I ended up with double dispatch. If I add virtual void apply(FooOwnerVisitor*) = 0; function to FooOwner and define FooOwnerVisitor interface nearby, then I can add any f开发者_如何学Pythonunctionality for FooOwner derivatives without affecting FooN hierarchy and without dynamic_cast.


I don't think anyone's clear on your requirement, but this is my best guess at addressing it... illustrating how to handle what you're calling the "dependency chain" in a template solution. If this doesn't help, but has any relevancy, then explaining it and the problems would help people help you. If you want to apply algorithmic loops over the Foo<> objects I can illustrate how to do that....

#include <iostream>

struct Abstract_Bar
{
    virtual void f() const = 0;
};

struct Bar1 : Abstract_Bar
{
    void f() const { std::cout << "Bar1\n"; }
};

struct Bar2 : Abstract_Bar
{
    void f() const { std::cout << "Bar2\n"; }
};

template <int N>
struct Foo
{
    typedef Foo<N - 1> Lower;
    typedef Foo<N + 1> Higher;

    void f() const { std::cout << "Foo<N>\n"; }

    Higher* higher_;
};

template <>
struct Foo<1>
{
    typedef Foo<2> Higher;

    void f() const { std::cout << "Foo<1>\n"; }

    Higher* higher_;
};

template <>
struct Foo<4>
{
    typedef Foo<3> Lower;
    typedef Abstract_Bar Higher;

    void f() const { std::cout << "Foo<4>\n"; }

    Higher* higher_;
};

int main()
{
    Foo<1> foo1;
    Foo<2> foo2;
    Foo<3> foo3;
    Foo<4> foo4;
    foo1.higher_ = &foo2;
    foo2.higher_ = &foo3;
    foo3.higher_ = &foo4;
    Bar1 bar1;
    foo4.higher_ = &bar1;

    foo1.f();
    foo2.f();
    foo3.f();
    foo4.f();

    foo1.higher_->f();
    foo2.higher_->f();
    foo3.higher_->f();
    foo4.higher_->f();

    // switch to another type of "Bar"...
    Bar2 bar2;
    foo4.higher_ = &bar2;
    foo4.higher_->f();
}


I ended up with double dispatch. If I add virtual void apply(FooOwnerVisitor*) = 0; function to FooOwner and define FooOwnerVisitor interface nearby, then I can add any functionality for FooOwner derivatives without affecting FooN hierarchy and without dynamic_cast. So my problem actually wa two problems tha have own solutions. First - how to make FooN classes from different owners compatible - inherit from owner interface. Second - how to avoid dynamic casting of FooNOwner derived classes - use Visitor pattern. One must consider to separate a problem into smaller ones and combine atomic solutions.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜