0

I am trying to utilize an abstract template base class. The compiler is giving errors in RowArray.cpp that the members rowPntr, and rowSize are "not declared in this scope." Both are protected members from the abstract class AbsRow. I am guessing that this design is not possible because it utilizes virtual functions, which are dynamical bound at run time, but at the same time uses a template which is bound at compile time. Perhaps mixing the two is the issue? What I would like to know is if my design is possible, and why am I getting these compiler errors? I did also forget to mention that when creating a RowArray object RowArray<int> obj(5); I get link error 2019 in visual studio and in Qt creator it tells me undefined reverence to RowArray constructor and destructor.

Abstract class 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;
};

Derived Class 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];
}

Main

#include "rowarray.h"

int main()
{
    RowArray<int> row(7);
}
Ritchie Shatter
  • 185
  • 1
  • 4
  • 14
  • Does `this->rowPntr` and `this->rowSize` help? – James Adkison Mar 10 '16 at 00:13
  • I had thought of that but didn't bother to try because I convinced myself it wasn't the issue. I'm shacking my head in shame. – Ritchie Shatter Mar 10 '16 at 00:15
  • 1
    Possible duplicate of [Derived template-class access to base-class member-data](http://stackoverflow.com/questions/1120833/derived-template-class-access-to-base-class-member-data) – James Adkison Mar 10 '16 at 00:16
  • It's an oddity that isn't normally required but comes into play sometimes in template classes, see the duplicate question. – James Adkison Mar 10 '16 at 00:17
  • Here's another [duplicate](http://stackoverflow.com/questions/27479960/derived-template-class-access-to-base-class-member-data-for-dependent-name) – James Adkison Mar 10 '16 at 00:18

3 Answers3

1

You can address that basically in two ways... Taking a shortened example of your RowArray.cpp ... (I also fixed a problem in your new expression)

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;
    }
}
WhiZTiM
  • 21,207
  • 4
  • 43
  • 68
0

I think error comes from the fact that you are putting template code (the derived class is still a template) into a CPP file. The compiler has to see the entire template implementation, which usually means putting the whole thing in a header file.

Another problem is that the derived class constructor assumes that rowPntr of of type int* but it is really T*.

Darrin Cullop
  • 1,170
  • 8
  • 14
  • I would up vote this if I had the rep. Thanks. The book I am reading never explicitly stated this, but it is shown in the code examples. I missed that completely. Thanks! – Ritchie Shatter Mar 10 '16 at 07:27
  • If it helped resolve your issue, you could accept it as the answer to the question. You're the original asker, so its up to you. – Darrin Cullop Mar 10 '16 at 10:24
0

The root cause for the problem here is, it is expected to have function definitions for template class in .h file itself. If you are not doing that compiler won't be able to link the definition from the .cpp file. There are few hacks to overcome this. One is to have an explicit template initialization in the .cpp file.

At the of RowArray.cpp add

template class AbsRow<int>;
template class RowArray<int>;

Nikhil Augustine
  • 187
  • 2
  • 12