mardi 5 avril 2016

Derive from class declared in private scope

I am currently refactoring some legacy code and would like to factorize a multiple if...elseif... statement into a series of classes implementing various strategies.

Since I have to access the original object's internals, I'm going to declare the new classes as nested classes; since nobody from the external world should access them, I'd prefer to declare them in private scope.

For the sake of exposing as few implementation details as possible, I was wondering whether it's possible to only forward-declare the base strategy class in the header file, and place all subclasses declaration in the implementation file. Code example as follows:

-- header file

class MyUglyClass
{
private:
    class IStrategyBase;
    IStrategyBase* sPtr;
    // class ActualImplementation; // this is what I'd like to avoid
    // class YetAnotherImplementation; // as above
    // blah blah blah
};

-- implementation file

class MyUglyClass::IStrategyBase
{
    virtual ResultType DoSomething(SomeType someParameter) = 0;
    // could expose some MyUglyClass members, since 
    // derived classes wouldn't inherit friendship
};

class ActualImplementation: public MyUglyClass::IStrategyBase
{
    ResultType DoSomething(SomeType someParameter) override
    {
        // Do actual work
    }
}

class YetAnotherImplementation: public MyUglyClass::IStrategyBase
{
    ResultType DoSomething(SomeType someParameter) override
    {
        // Doing something really tricky & clever for corner cases
    }
}

Of course the compiler complains since IStrategyBase is not accessible; I could work around this by fwd-declaring ActualImplementation and YetAnotherImplementation into the header file together with IStrategyBase, but I'd rather avoid this, since I would need to change the header if a new strategy was needed.

I could also declare IStrategyBase in public scope, however I would prefer to keep it private to avoid other people messing with it.

Of course I'm assuming that non-fwd-declared subclasses wouldn't inherit friendship with MyUglyClass, so I would have to expose relevant data the IStrategyBase protected members.

Is there any way to achieve this I could be missing?

Aucun commentaire:

Enregistrer un commentaire