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();
//...