【问题标题】:C++ Abstract Template ClassC++ 抽象模板类
【发布时间】:2016-03-10 00:09:46
【问题描述】:

我正在尝试使用抽象模板基类。 编译器在 RowArray.cpp 中给出了成员 rowPntr 和 rowSize “未在此范围内声明”的错误。两者都是抽象类 AbsRow 的受保护成员。我猜这种设计是不可能的,因为它利用了在运行时动态绑定的虚函数,但同时使用了在编译时绑定的模板。也许将两者混合是问题?我想知道我的设计是否可行,为什么会出现这些编译器错误?我也确实忘记提及,在创建 RowArray 对象RowArray<int> obj(5); 时,我在 Visual Studio 和 Qt 创建器中收到链接错误 2019,它告诉我未定义对 RowArray 构造函数和析构函数的尊重。

抽象类 AbsRow.h

template <typename T>
class AbsRow
{
public:

     virtual int getSize()const = 0;
     virtual T getValue(int index)const = 0;

protected:

     T *rowPntr;
     int rowSize;
};

派生类RowArray.h

#include "absrow.h"

template <class T>
class RowArray : public AbsRow<T>
{
public:

    RowArray(const int rows);
    virtual ~RowArray();

    virtual T getValue(int index) const override;
    virtual int getSize() const override;

    void setValue(int row, int value);
};

RowArray.cpp

#include "rowarray.h"
#include <cstdlib>

template <class T>
RowArray<T>::RowArray(const int rows)
{
    rowSize = rows;
    rowPntr = new int[rows];

    for(int index = 0; index < rows; index++)
    {
        rowPntr[index] = (rand() % 90) + 10;
    }
}

template <class T>
RowArray<T>::~RowArray()
{
    delete [] rowPntr;
}

template <class T>
void RowArray<T>::setValue(int row, int value)
{
    rowPntr[row] = value;
}

template <class T>
int RowArray<T>::getSize() const
{
    return rowSize;
}

template <class T>
T RowArray<T>::getValue(int index) const
{
    return rowPntr[index];
}

主要

#include "rowarray.h"

int main()
{
    RowArray<int> row(7);
}

【问题讨论】:

  • this-&gt;rowPntrthis-&gt;rowSize 有帮助吗?
  • 我曾想过,但没有费心去尝试,因为我说服自己这不是问题所在。我羞愧地摇头。
  • 这是一个奇怪的现象,通常不需要,但有时会在模板类中发挥作用,请参阅重复的问题。
  • 这是另一个duplicate

标签: c++ templates


【解决方案1】:

您基本上可以通过两种方式解决这个问题...以您的 RowArray.cpp 为例... (我还修复了您的 new 表达式中的一个问题)

template <class T>
RowArray<T>::RowArray(const int rows)
{
    AbsRow<T>::rowSize = rows
    // or
    //this->rowSize = rows;

    AbsRow<T>::rowPntr = new T[rows];   ///Corrected 'int' to 'T' because rowPntr is of type 'T*' in your AbsRow class
    // or
    //this->rowPntr = new T[rows];

    for(int index = 0; index < rows; index++)
    {
        AbsRow<T>::rowPntr[index] = (rand() % 90) + 10;
        // or
        //this->rowPntr[index] = (rand() % 90) + 10;
    }
}

【讨论】:

    【解决方案2】:

    我认为错误来自您将模板代码(派生类仍然是模板)放入 CPP 文件的事实。编译器必须查看整个模板实现,这通常意味着将整个内容放在头文件中。

    另一个问题是派生类构造函数假定rowPntr 的类型为int*,但它实际上是T*

    【讨论】:

    • 如果我有代表,我会投票赞成。谢谢。我正在阅读的书从未明确说明这一点,但它显示在代码示例中。我完全错过了。谢谢!
    • 如果它有助于解决您的问题,您可以接受它作为问题的答案。您是最初的提问者,一切由您决定。
    【解决方案3】:

    这里问题的根本原因是,.h 文件本身中应该有模板类的函数定义。如果您不这样做,编译器将无法链接 .cpp 文件中的定义。很少有技巧可以克服这一点。一种是在 .cpp 文件中进行显式模板初始化。

    在RowArray.cpp的添加

    template class AbsRow&lt;int&gt;;
    template class RowArray&lt;int&gt;;

    【讨论】:

      猜你喜欢
      • 2011-06-12
      • 1970-01-01
      • 2018-12-28
      • 2014-11-02
      • 2021-12-12
      • 1970-01-01
      • 2015-11-18
      • 2015-01-05
      • 1970-01-01
      相关资源
      最近更新 更多