如何在switch语句中正确初始化不同的派生类?

时间:2019-02-07 04:06:41

标签: c++ pointers inheritance abstract dynamic-memory-allocation

我有以下代码,具有基类Base的类层次结构,以及几个派生类Derived1,Derived2,Derived3 ...等等。

switch(i){
    case 1:{
        Derived1* d1;
        generateD1(d1);
        otherFunc(d1); //function signature is otherFunc(Base*)
        break;
    }
    case 2:{
        Derived2* d2;
        generateD2(d2);
        otherFunc(d2);
        break;
    }
    ...  //goes on for many cases
}

如何使用继承机制来改进上述代码?

2 个答案:

答案 0 :(得分:2)

类似这样的东西:

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

        virtual void generate() = 0 {}

        virtual void other() = 0 {}
};

class Derived1 : public Base
{
    public:
        virtual void generate() override {}

        virtual void other() override {}
};

class Derived2 : public Base
{
    public:
        virtual void generate() override {}

        virtual void other() override {}
};

int main()
{
    int i;
    Base *b;
    switch(i)
    {
        case 1:
            b = new Derived1;
            break;
        case 2:
            b = new Derived2;
            break;
        ...
    }
    b->generate();
    b->other();
    ...
    delete b;
    return 0;
}

您可以删除generate()方法,而只使用构造函数:

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

        virtual void other() = 0 {}
};

class Derived1 : public Base
{
    public:
        Derived1() {}

        virtual void other() override {}
};

class Derived2 : public Base
{
    public:
        Derived2() {}

        virtual void other() override {}
};

int main()
{
    int i;
    Base *b;
    switch(i)
    {
        case 1:
            b = new Derived1;
            break;
        case 2:
            b = new Derived2;
            break;
        ...
    }
    b->other();
    ...
    delete b;
    return 0;
}

答案 1 :(得分:2)

FYI,除了@SidS的解决方案之外,我们还可以将生成过程提取为一个简单的函数,该函数返回Base的指针,如下所示。 在这里,我还使用std::unique_ptr,这使我们的代码具有RAII语义更加安全,然后您可以忽略调用delete b

#include <stdexcept>
#include <memory>

std::unique_ptr<Base> create(int i) // C++11
{
    switch(i)
    {
        case 1:
            return std::make_unique<Derived1>(); // C++14
            break;
        case 2:
            return std::make_unique<Derived2>();
            break;
        default:
            throw std::logic_error("unsupported.");
    }
}

然后,呼叫方将更简单,如下所示:

DEMO

auto b = create(i);
b->generate();
b->other();