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

C++ 如何避免无法实例化抽象类的问题,c++,C++,我在使用库时遇到以下问题(它是库,但无所谓)。 我想做如下的事情,但我想我不能,因为基类是抽象的。换句话说,我不能进行后期绑定,因为我不能实例化抽象类的对象 我有一个抽象类和两个派生类。main()的代码不正确,因为我无法创建对象的基 //An abstract class class Base { protected: Base() {} public: void doSomething() = 0; }; class DerivedA : public Base { pub

我在使用库时遇到以下问题(它是库,但无所谓)。
我想做如下的事情,但我想我不能,因为基类是抽象的。换句话说,我不能进行后期绑定,因为我不能实例化抽象类的对象

我有一个抽象类和两个派生类。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
}
有什么方法可以避免我的“解决方案”吗? 提前谢谢你。

你可以

Base*对象

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


theObject->doSomething()

只有基类中的虚拟方法可以是抽象的,因此您的第一个类应该具有如下类型的doSomething:

虚空doSomething()=0


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

您可以将其包装在工厂函数中

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();
//...
std::唯一的getObject(…路径)
{
const int theType=someSpecialFunction(路径);
开关(类型)
{
案例1://衍生对象
返回std::make_unique(openObjectOfTypeA(thePath));
案例2://一个derivedB对象
返回std::make_unique(openObjectOfTypeB(路径));
}
返回空ptr;
}
//...     
std::unique basePtr=getObject(路径);
basePtr->doSomething();
//...

如果你没有可用的c++14,你可以用boost
共享的\u ptr
或原始指针替换
唯一的\u ptr

你不能有实例,但你可以有指针,你可以使用
基*theObject
。无论如何
Base theObject=DerivedA()被破坏(依赖于
Base
是抽象的),因为对象切片语言提供多态性,所以您不必在type&downcast上分派。@tobi303关于对象切片问题。如果我只使用指针基*theObject来调用doSomething(),没有问题吧?没有指针没有slicingI无法更改函数openObjecOfTypeA/B(它们是库的一部分)。因此,我必须做一些类似的事情:
derivedatmpobj=openObjectOfTypeA(路径);对象=&tmpObj和开关后
对象->剂量测量
。正当非常感谢你。这个方法有危险吗?@pablo_worker
对象的指针应该指向一个有效的地址,确保你没有取消引用不包含有效地址的内容。
tmpObj
可能超出范围,您必须注意。分配
Base*theObject=nullptr也很好
因此,在取消引用之前,您可以始终检查
nullptr
。确定。非常感谢。@pablo_工人您必须小心
&tmpObj。如果在switch语句中创建
tmpObj
,则指针在切换后将无效。这就是P0W在这里的意思。
tmpObj
消失的瞬间
object
将无效,您无法通过对照
null
检查
object
来捕获此特定错误。
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();
//...