Question

I'm wondering how to avoid code-duplication in a scenario as given below.

(There's this question:
How do I check if an object's type is a particular subclass in C++?
The answer there is that it's not possible and even with dynamic casts member access wouldn't be possible, I guess.)

So I'm wondering how you avoid having almost the same code in different methods, where just one method would have a few additional operations.

class Basic {
    ...
}

class Advanced : public Basic {
    ...
}


AnotherClass::lengthy_method(Basic *basic) {
    // do a lot of processing, access members of basic

    if (*basic is actually of class Advanced)
        // do one or a few specific things with members of Advanced

    // more processing just using Basic

    if (*basic is actually of class Advanced)
        // do one or a few specific things with members of Advanced

    // more processing just using Basic
}


Also from a design perspective AnotherClass::lengthy_method wouldn't want to be defined in Basic or Advanced since it's not really belonging to either of them. It's just operating on their kind.

I'm curious what the language experts know and I hope there's a nice solution, maybe at least through some functionality from C++11.

Was it helpful?

Solution

dynamic_cast can be used here, as long as the Advanced members you want to access are declared as public, or AnotherClass is declared as a friend of Advanced:

AnotherClass::lengthy_method(Basic *basic) {
    // do a lot of processing, access members of basic

    Advanced *adv = dynamic_cast<Advanced*>(basic);
    if (adv != NULL) {
        // use adv as needed...
    }

    // more processing just using Basic

    if (adv != NULL) {
        // use adv as needed...
    }

    // more processing just using Basic
}

Another option is to use polymorphism instead of RTTI. Expose some additional virtual methods in Basic that do nothing, and then have Advanced override them:

class Basic {
    ...
    virtual void doSomething1() {}
    virtual void doSomething2() {}
}

class Advanced : public Basic {
    ...
    virtual void doSomething1();
    virtual void doSomething2();
}

void Advanced::doSomething1() {
    ...
}

void Advanced::doSomething2() {
    ...
}    

AnotherClass::lengthy_method(Basic *basic) {
    // do a lot of processing, access members of basic

    // do one or a few specific things with members of Advanced
    basic->doSomething1();

    // more processing just using Basic

    // do one or a few specific things with members of Advanced
    basic->doSomething2();

    // more processing just using Basic
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top