0

I'm sorry the title is so nasty, it's very hard to explain

class BaseState {
protected:
    BaseState();
public:
    void Some();
    void Useful();
    void Methods();
};

class UsefulState: public BaseState {
public:
    void moreUsefulStuff();
};

class SomeUsefulBase {
protected:
    SomeUsefulBase(BaseState* pState) { state = pState; }
    void UsefulMethods() { state->Some(); }
    void Andthings() { state->Useful(); }
public:
    virtual void doSomething() = 0;
protected:
    BaseState* state;
};

class SomethingUseful: public SomeUsefulBase {
public:
    SomethingUseful(UsefulState* pState): SomeUsefulBase(pState) {
        usefulState = pState;
    }
    virtual void doSomething() { usefulState->moreUsefulStuff();} 
protected:
    UsefulState* usefulState;
};

then:

SomethingUseful whatever(new UsefulState());

It's not important where things are allocated but there will be a lot of classes derived from SomethingUseful that will use a UsefulState however, all the member functions of SomeUsefulBase will use the state, but as a BaseState

I am hoping there is a better way than using two members (UsefulState and BaseState pointers in the definitions), I've thought of a union and a template, but that would be ugly.

I also don't want to litter my code with casts, I'm wondering if there is a nicer notation.

There will be one UsefulState per operation, and a large tree structure will be formed of various subclasses of SomethingUseful and/or subclasses of SomethingUsefulBase where a UsefulState pointer is expected.

Addendum: Not sure what's up with SO's syntax highlighting! It seems to be using case to decide if it wants to colour things blue or not.... not sure how that works.

Addendum 2: In the use this example is derived from there is one state per operation but many things derived from SomeUsefulBase, the derived classes will create each other to form a large tree structure (god I sound noobish) but will all require the use of the derived state.

4

1 回答 1

0

这听起来像是标准的“抽象工厂”类型的情况:

struct AbstractGadget { virtual ~AbstractGadget() {} };
struct AbstractWidget { virtual ~AbstractWidget() {} };
struct AbstractThingy { virtual ~AbstractThingy() {} };

struct AbstractFactory
{
    virtual ~AbstractFactory() {}

    virtual std::unique_ptr<AbstractGadget> make_gadget() = 0;
    virtual std::unique_ptr<AbstractGadget> make_widget() = 0;
    virtual std::unique_ptr<AbstractGadget> make_thingy() = 0;
};

用法:

struct Gadget1 : AbstractGadget { /* ... */ };
struct Widget1 : AbstractWidget { /* ... */ };
struct Thingy1 : AbstractThingy { /* ... */ };

struct Factory1 : AbstractFactory
{
    virtual std::unique_ptr<AbstractGadget> make_gadget()
    {
        return { new Gadget1; }
    }

    // ...
};

等等等等Factory2Widget3这里也有很多使用模板消除样板代码的潜力。

可能会给消费者一个AbstractFactory & f和调用f.make_gadget()等来创建合适类型的对象。

于 2013-08-27T23:24:09.033 回答