【问题标题】:Cannot declare variable 'ML' to be of abstract type 'MyList<int>' when using template with virtual functions使用带有虚函数的模板时,无法将变量“ML”声明为抽象类型“MyList<int>”
【发布时间】:2021-01-10 17:30:06
【问题描述】:

晚安。 我在 C++ 中实现一个包含模板和虚函数的赋值,所以当我调用参数化构造函数时,它给了我错误“无法将变量 'ML' 声明为抽象类型'MyList'”

    #include <bits/stdc++.h>
using namespace std;

template <typename T>
class MyList
{
protected:
    int arraySize;
    T *arr;
public:
    MyList<T>(){}
    MyList<T>(int arraySize)
    {
        this->arraySize = arraySize;
        this->arr = new T[arraySize];
    }
    int getSize()
    {
        return this->arraySize;
    }
    //virtual void addElem() = 0;
    virtual int getElem() = 0;
    //virtual bool isEmpty() = 0;
    ///virtual bool isFull() = 0;
    ///virtual void clearItems() = 0;
    ~MyList()
    {
        delete [] this->arr;
    }
};

template <typename C>
class MyStack : public MyList<C>
{
public:
    int getElem()
    {
        return 2;
    }
};
int main()
{
    MyStack <int> MS;
    MyList <int> ML(5);
    MS.getElem();
}

很抱歉将源代码、main 和 headers 实现在一个文件中,但它是分配交付所必需的。 提前致谢。

【问题讨论】:

  • 你有一个带有纯虚函数的抽象类。这样的类不能被实例化(这就是抽象的意思)——它需要派生,并且那些纯虚函数需要在派生类中被覆盖。 MyList&lt;int&gt; 是模板实例化这一事实无关紧要。
  • 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange 网络上发帖,您已在 CC BY-SA 4.0 license 下授予 Stack Exchange 分发该内容的不可撤销的权利(即无论您未来的选择如何)。根据 Stack Exchange 政策,帖子的非破坏版本是分发的版本。因此,任何破坏行为都将被撤销。如果您想了解更多关于删除帖子的信息,请参阅:How does deleting work?

标签: c++ templates virtual-functions


【解决方案1】:

这就是错误所说的。您不能制作抽象类的对象。这是一个具有至少一个纯虚函数的类。但是,您可以实例化 MyStack,因为它为父类 MyList 的纯虚函数 getElem 提供了定义。

【讨论】:

  • 好的,我明白了,但是在赋值说明中我应该创建一个参数化构造函数,它在 MyList 中定义 Array_Size 这是抽象类,那么我如何确定数组大小?
  • @MohamedWael 为什么需要 getElem 是虚拟的?
  • 不幸的是,这是拼贴作业的说明,除了 getSize() 之外的所有函数都是纯虚拟的。
  • 说明: 纯虚函数: - addElem 添加元素 - getElem 从数组中删除元素后返回元素。 - isEmpty 如果数组为空则返回 true - isFull() 如果数组已满则返回 true - clearItems() 清空数组;
  • 你不能同时拥有纯虚函数和创建该类的对象
【解决方案2】:

干脆去掉ML,反正你不用它。向MyStack 添加一个int 构造函数,该构造函数调用myListint 构造函数

template <typename C>
class MyStack : public MyList<C>
{
public:
    MyStack(int arraySize) : MyList<C>(arraySize){} // <- add this

    int getElem()
    {
        return 2;
    }
};

然后你可以像这样使用它:

int main()
{
    MyStack <int> MS(5);
    MS.getElem();
}

另外,附带说明一下,MyList 不符合Rule of 3/5/0,因为它缺少复制构造函数和复制赋值运算符。而且它的默认构造函数根本没有初始化类成员。

【讨论】:

    猜你喜欢
    • 2013-03-09
    • 2016-07-04
    • 2012-07-23
    • 2017-12-10
    • 1970-01-01
    • 2017-12-08
    • 2016-08-22
    • 1970-01-01
    • 2010-10-23
    相关资源
    最近更新 更多