如何避免无法实例化抽象类的问题

时间:2016-11-14 15:27:20

标签: c++

我在使用库时遇到以下问题(它是hdf5库,但它并不重要。)
我想做类似下面的事情,但我认为我不能,因为Base类是抽象的。换句话说,我无法进行后期绑定,因为我无法实例化抽象类的对象。

我有一个抽象类和2个派生类。 main()的代码不正确,因为我无法做对象;

//An abstract class
class Base
{
protected:
    Base() {}
public:
    void doSomething() = 0;
};

class DerivedA : public Base
{
public:
    DerivedA() : Base() {}
    void doSomething() {cout << "I am a DerivedA" << endl;}
};

class DerivedB : public Base
{
public:
    DerivedB() : Base() {}
    void doSomething() {cout << "I am a DerivedB" << endl;}
};


int main()
{
    // A special function returns the type of object that it is placed at "thePath".  
    int theType = someSpecialFunction(thePath);
    Base theObject;   //This is not possible.
    switch (theType)
    {
        case 1: //A derivedA object
        {
             theObject = openObjectOfTypeA(thePath); //Special function of the library.            
             break;
        }
        case 2: //A derivedB object
        {
             theObject = openObjectOfTypeB(thePath); //Special function of the library
             break;
        }
    }

    theObject.doSomething();
    //whatever
}

我可以做以下事情。但是,在真实情况下,我会以大量重复代码结束。

int main()
{
    // A special function returns the type of object that it is placed at "thePath"
    int theType = someSpecialFunction(thePath);
    switch (theType)
    {
        case 1: //A derivedA object
        {
             DerivedA theObject = openObjectOfTypeA(thePath);
             theObject.doSomething();
             break;
        }
        case 2: //A derivedB object
        {
             DerivedB theObject = openObjectOfTypeB(thePath);
             theObject.doSomething();
             break;
        }
    }
    //whatever
}

有什么方法可以避免我的解决方案&#34;? 提前谢谢。

3 个答案:

答案 0 :(得分:4)

你可以拥有

Base* theObject;

并使用指针调用成员函数。您必须更改openObjectOfTypeA/B的返回类型才能返回指向Base类的指针。

theObject->doSomething();

答案 1 :(得分:1)

只有基类中的虚方法可以是抽象的,所以你的第一个类应该有这样的原型doSomething:

virtual void doSomething()= 0;

您可以使用指针来使用“type”参数。指向基类(例如Base)的指针可以指向任何派生类(例如DerivedA或DerivedB)。然后,当你想调用doSomething()时,它将调用子类的doSomething。

答案 2 :(得分:1)

您可以将其包装在工厂功能中。

pytest

如果您没有c ++ 14可用,则可以使用boost std::unique<Base> getObject( ... thePath) { const int theType = someSpecialFunction(thePath); switch (theType) { case 1: //A derivedA object return std::make_unique<DerivedA>(openObjectOfTypeA(thePath)); case 2: //A derivedB object return std::make_unique<DerivedB>(openObjectOfTypeB(thePath)); } return nullptr; } //... std::unique<Base> basePtr = getObject(path); basePtr->doSomething(); //... 或原始指针替换unique_ptr