0

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.

Community
  • 1
  • 1
Phantrast
  • 639
  • 1
  • 9
  • 18

1 Answers1

2

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
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks! It's very good to know that member access of `Advanced` is actually possible. – Phantrast May 10 '14 at 22:43
  • Why did you think it was not possible? – Remy Lebeau May 10 '14 at 22:53
  • To me it is surprising that the compiler allows access to a member that might not exist. – Phantrast May 10 '14 at 23:06
  • 1
    It won't. You cannot `dynamic_cast` an object pointer to another *unrelated* type. If the cast succeeds, you have a valid pointer and can access members of the type you casted to. If the cast fails, you have a NULL pointer and cannot access the failed type's members. – Remy Lebeau May 11 '14 at 02:28