Downcasting best-practice (C++)

我怕爱的太早我们不能终老 提交于 2019-12-24 01:16:08

问题


Static code analysis tools tend to ramble a lot about "downcasting a base class to a derived class" and I also found a couple of coding standard guides, which mention not to do this so I was wondering what is the best-practice way.

Here's my use case:

I have a Base (interface), DerivedA, DerivedB classes and then an array containing Base pointers.

Then I iterate through the array and based on a flag, I determine if the object is DerivedA or DerivedB, cast it down and do some random stuff to the object from the outside.

Basically something like this:

// arr is of type Base**
for (int i = 0; i < size; ++i)
{
    // doMagic has an overload for both types
    if (arr[i]->isDerivedA())
    {
        doMagic(reinterpret_cast<DerivedA*>(arr[i]));
    }     
    else if (arr[i]->isDerivedB())
    {
        doMagic(reinterpret_cast<DerivedB*>(arr[i]));
    }
}

Bout the reinterpret, I cannot use dynamic_cast due to embedded platform restrictions (the same for C++11), but the Base class being an interface guarantees that the object is either DerivedA or DerivedB.

I could make DerivedA and DerivedB only implement pure virtual calls, thus i wouldn't have to worry about downcasting anything, but the DerivedA and DerivedB classes are very much specialized and doMagic does completely different things with the instances...

So I was wondering how you guys approach this - having a single array of very different objects, but inherited from a single base, iterating through them and doing some specialized stuff from the outside.


回答1:


You probably should try to use visitor pattern. Here is a simple example:

#include <cstdio>

class A;
class B;
class Visitor {
public:
    void visit(A &a) {
        printf("Visited A\n");
    }

    void visit(B &) {
        printf("Visited B\n");
    }
};


class A {
public:
    virtual ~A() { }

    virtual void applyVisitor(Visitor &v) {
        v.visit(*this);
    }
};

class B : public A {
public:
    ~B() override { }

    void applyVisitor(Visitor &v) override {
        v.visit(*this);
    }
};


int main() {
    A a;
    B b;

    Visitor v;

    a.applyVisitor(v);
    b.applyVisitor(v);


    return 0;
}



回答2:


If you know that a pointer of a base class points to an object of a derived class, you may use static_cast. The compiler will insert appropriate code to adjust offsets, unlike reinterpret_cast or a C-Cast.



来源:https://stackoverflow.com/questions/42041294/downcasting-best-practice-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!