为什么我们不能声明std :: vector <AbstractClass>?

我花了很多时间在C#中进行开发,但是我注意到,如果您声明一个抽象类以便将其用作接口,则无法实例化此抽象类的向量来存储子类的实例。


#pragma once

#include <iostream>

#include <vector>


using namespace std;


class IFunnyInterface

{

public:

    virtual void IamFunny()  = 0;

};


class FunnyImpl: IFunnyInterface

{

public:

    virtual void IamFunny()

    {

        cout << "<INSERT JOKE HERE>";

    }

};


class FunnyContainer

{

private:

    std::vector <IFunnyInterface> funnyItems;

};

声明抽象类向量的行在MS VS2005中导致此错误:


error C2259: 'IFunnyInterface' : cannot instantiate abstract class

我看到一个明显的解决方法,即将IFunnyInterface替换为以下内容:


class IFunnyInterface

{

public:

    virtual void IamFunny()

    {

        throw new std::exception("not implemented");

    }

};

这是C ++明智的解决方法吗?如果没有,是否有像boost这样的第三方库可以帮助我解决这个问题?



白板的微信
浏览 402回答 3
3回答

忽然笑

您不能实例化抽象类,因此抽象类的向量不能工作。但是,您可以使用指向抽象类的指针向量:std::vector<IFunnyInterface*> ifVec;这也使您可以实际使用多态行为-即使该类不是抽象的,按值存储也会导致对象切片的问题。

Smart猫小萌

您无法创建抽象类类型的向量,因为您无法创建抽象类的实例,并且诸如std :: vector之类的C ++标准库容器将存储值(即实例)。如果要执行此操作,则必须创建一个指向抽象类类型的指针向量。您的工作流程将无法正常工作,因为虚函数(这就是您首先要抽象类的原因)仅在通过指针或引用调用时才起作用。您也不能创建引用向量,因此这是您必须使用指针向量的第二个原因。您应该意识到C ++和C#几乎没有共同之处。如果您打算学习C ++,则应该从头开始,并阅读专门的C ++教程,例如Koenig和Moo的Accelerated C ++。

慕森王

在这种情况下,我们甚至不能使用以下代码:std::vector <IFunnyInterface*> funnyItems;要么std::vector <std::tr1::shared_ptr<IFunnyInterface> > funnyItems;因为FunnyImpl和IFunnyInterface之间没有IS A关系,并且由于私有继承,FUnnyImpl和IFunnyInterface之间也没有隐式转换。您应该按照以下方式更新代码:class IFunnyInterface{public:&nbsp; &nbsp; virtual void IamFunny()&nbsp; = 0;};class FunnyImpl: public IFunnyInterface{public:&nbsp; &nbsp; virtual void IamFunny()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; cout << "<INSERT JOKE HERE>";&nbsp; &nbsp; }};
打开App,查看更多内容
随时随地看视频慕课网APP