Calling a Child class' method when processing

2019-07-27 11:58发布

问题:

This question seems like it might be somewhat common, but I didn't find anything when scowering StackOverflow or the interwebs.

I came across a method in a C++ class that takes a list of (for example) Parent objects. For this example, assume that there are two classes that derive from Parent: Child1 and Child2.

For each object in the list, the method checks if the object is of type Child2 (via a IsOfType() method that each class implements), and if so, it calls a method that is only provided by the Child2 class.

Is this an issue in that the list-processing method cannot treat each object the same? I've seen this done in other places as well, so it seems it might be a common practice to some degree.

One option might be to declare the Child2 method in the Parent class so that all Parent objects implement it. However, in this case, only the Child2 class would actually implement any behavior when overriding the method.

Your thoughts? Thanks in advance!

回答1:

If your IsOfType() test passes, you can cast the (pointer to the) parent object to a Child2 object and access its specific member functions.

EDIT: This depends on your design and on how strict you ensure the IsOfType() implementation will give correct answers (i.e. it also works when you add new subclasses in a week). It might be safer to make use of the builtin Typeid instead. Implementing every possible method any child would ever have in the parent would be difficult, so upcasting is ok when the method is really semantically specific to the Child2 class.



回答2:

I think the following is a better solution for this problem.

class Parent {
public:
   virtual int doSomething() {}
};

class Child1 : public Parent {
};

class Child2 : public Parent {
public:
    virtual int doSomething();

Now you just omit the IsOfType call altogether and call doSomething on all of the pointers passed to you.

The only good reason I can think of as to why you'd have an IsOfType function is if you don't have control over the Parent class and can't modify it to add the doSomething method.



回答3:

You could declare the new method in an interface that only Child2 implements. You could then use dynamic_cast<ISomeOtherInterface> to see if the object supports the extended feature. This cast will result in a null pointer for objects that don't support the additional interface.

This would allow you to create other objects that implement this feature, without requiring your list processing to know about each specific object type.



回答4:

You might find the Visitor Pattern useful in this instance. This will allow the objects themselves (child1, child2 etc) to call you back with their static type and take appropriate action.



标签: c++ oop