Aggregates, templating, and dynamic vectors - c++

I keep getting 3 errors. They're all related to the way I'm aggregating templates I'm assuming but i can't find anything to help me figure this out. My teacher wasn't super clear on how we're supposed to get the output he wants us to get.
In file included from main.cpp:10:
./Table.h:15:9: error: use of class template 'RowAray' requires template arguments
Here is what i wrote
RowAray.cpp
#ifndef ROWARAY_H // if constant ROWARAY_H not defined do not execute
#define ROWARAY_H // defines constant ROWARAY_H
#include <iostream>
#include <new> // Needed for bad_alloc exception
#include <cstdlib> // Needed for the exit function
template <class T>
class RowAray{
private:
int size;
T *rowData;
void memError(); // Handles memory allocation errors
void subError(); // Handles subscripts out of range
public:
RowAray(T); //used to construct row Array object
~RowAray(){delete [] rowData;} //used to deallocate dynamically allocated memory from Row array
int getSize(){return size;} //inline accessor member function used to return length of Row array
T getData(int i){return (( i >=0&& i < size)?rowData[i]:0);} //
T &operator[](const int &);
};
template <class T>
RowAray<T>::RowAray(T colSize){
size =colSize>1?colSize:1;
// Allocate memory for the array.
try
{
rowData = new T [size];
}
catch (bad_alloc)
{
memError();
}
// Initialize the array.
for (int count = 0; count < size; count++)
*(rowData + count) = rand()%90+10;
}
template <class T>
void RowAray<T>::memError()
{
cout << "ERROR:Cannot allocate memory.\n";
exit(EXIT_FAILURE);
}
template <class T>
void RowAray<T>::subError()
{
cout << "ERROR: Subscript out of range.\n";
exit(EXIT_FAILURE);
}
template <class T>
T &RowAray<T>::operator[](const int &sub)
{
if (sub < 0 || sub >= size)
subError();
else
return rowData[sub];
}
#endif /* ROWARAY_H */
Table.cpp
#ifndef TABLE_H
#define TABLE_H
#include "RowAray.h"
template <class T>
class Table{
private:
int szRow;
RowAray **records;
public:
Table(int,int); //used to construct Table object
~Table(); //used to deallocate dynamically allocated memory from Table object
int getSzRow(){return szRow;} //used to return row size
int getSize(int row){return records[row>=0?row:0]->getSize();} //used to return column size
T getRec(int, int); //used to return inserted random numbers of 2d arrays
};
template <class T>
Table<T>::Table(int r, int c ){
//Set the row size
this->szRow = r;
//Declare the record array
records = new RowAray*[this->szRow];
//Size each row
int allCol = c;
//Create the record arrays
for(int i=0;i<this->szRow;i++){
records[i]=new RowAray(allCol);
}
}
template <class T>
T Table<T>::getRec(int row, int col){
//if else statement used to return randomly generated numbers of array
if(row >= 0 && row < this->szRow && col >= 0 && col < records[row]->getSize()){
return records[row]->getData(col);
}else{
return 0;
}
}
template <class T>
Table<T>::~Table(){
//Delete each record
for(int i=0;i<this->szRow;i++){
delete records[i];
}
delete []records;
}
#endif /* TABLE_H */
main.cpp
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iomanip>
using namespace std;
//User Libraries
#include "RowAray.h"
#include "Table.h"
//Global Constants
//Function Prototype
template<class T>
void prntRow(T *,int);
template<class T>
void prntTab(const Table<T> &);
//Execution Begins Here!
int main(int argc, char** argv) {
//Initialize the random seed
srand(static_cast<unsigned int>(time(0)));
//Declare Variables
int rows=3,cols=4;
//Test out the Row with integers and floats
RowAray<int> a(3);
RowAray<float> b(4);
cout<<"Test the Integer Row "<<endl;
prntRow(&a,3);
cout<<"Test the Float Row "<<endl;
prntRow(&b,4);
//Test out the Table with a float
Table<float> tab1(rows,cols);
Table<float> tab2(tab1);
//Table<float> tab3=tab1+tab2;
cout<<"Float Table 3 size is [row,col] = Table 1 + Table 2 ["
<<rows<<","<<cols<<"]";
//prntTab(tab3);
//Exit Stage Right
return 0;
}
template<class T>
void prntRow(T *a,int perLine){
cout<<fixed<<setprecision(1)<<showpoint<<endl;
for(int i=0;i<a->getSize();i++){
cout<<a->getData(i)<<" ";
if(i%perLine==(perLine-1))cout<<endl;
}
cout<<endl;
}
template<class T>
void prntTab(const Table<T> &a){
cout<<fixed<<setprecision(1)<<showpoint<<endl;
for(int row=0;row<a.getSzRow();row++){
for(int col=0;col<a.getSize();col++){
cout<<setw(8)<<a.getRec(row,col);
}
cout<<endl;
}
cout<<endl;
}

"RowAray" is a template, with one template parameter:
template <class T>
class RowAray
See there? It's a template, one template parameter.
Now, over here:
template <class T>
class Table{
private:
int szRow;
RowAray **records;
See there? No template parameter when referring to the RowAray template, here. When using a template, its parameters must also be specified (unless they have a default, which is irrelevant here).
The fact that, here, you are defining a new template, Table, with one template parameter -- that's irrelevant.
You probably intended to use
RowAray<T> **records;
here; but that's just based on a cursory look at this pile of code so don't automatically take my word for it. You need to figure out what you intended to do here, and specify the correct template parameter.
This is not the only parameter-less reference in the shown code. You need to find, and fix all of them.
Furthermore, you also dumped:
using namespace std;
before proceeding and #includeing a bunch of header files, including standard library header files. This is a bad programming practice, and often creates subtle, and difficult to figure out compilation errors, if not outright wrong code. You must get rid of using namespace std; as well, especially when a bunch of #includes are involved.

Related

Non template friend function of 2 templated classes undefined reference error

Problem Statement:
Using 2 different Templated classes 1 matrix class and other 1 vectorimp class and using 1 friend function which is multiply function.
Error Location
multiply(matA,p);
in main.cpp
Issue:
As I am using non templated function with arugements as templated classes so I am getting error
undefined reference to `multiply(matrix<int>, vectorimp<int>)'
collect2.exe: error: ld returned 1 exit status
Error:
**** Build of configuration Debug for project Matrix_Vector_Multiplication ****
**** Internal Builder is used for build ****
g++ -oMatrix_Vector_Multiplication.exe Vector.o Matrix_Vector_Multiplication_main.o Matrix_Vector_Multiplication.o
Matrix_Vector_Multiplication_main.o: In function `main':
D:\C++ Eclipse projects\Matrix_Vector_Multiplication\Debug/../Matrix_Vector_Multiplication_main.cpp:25: undefined reference to `multiply(matrix<int>, vectorimp<int>)'
collect2.exe: error: ld returned 1 exit status
Build error occurred, build is stopped
Time consumed: 1741 ms.
matrix class with .h and .cpp file:
matrix.h
#pragma once
#include <iostream>
#include<vector>
#include <time.h>
#include <ostream>
#include "Vector.h"
#define LENGTH 3
#define WIDTH 3
//using namespace std;
template <typename T>
class vectorimp;
template <typename T>
class matrix
{
private:
T rows ;
T cols ;
T g[LENGTH];
T **mat;
public:
//Default constructor
matrix(T rows , T cols);
~matrix();
T **generatematrix(int rows, int cols);
void populatematrix(T *src, T size);
void print();
template<class T>
friend void multiply(matrix<T> p, vectorimp<T> v);
};
matrix.cpp
#include "Matrix_Vector_Multiplication.h"
#include <omp.h>
#include <stdio.h>
#include <iostream>
using namespace std;
template <class T>
matrix<T>::matrix (T rows , T cols) : rows(rows),cols(cols) {
this ->mat = generatematrix(this ->rows ,this ->cols );
}
template <class T>
matrix<T>::~matrix()
{
for(int i=0; i< this->rows; i++)
{
delete[] this ->mat[i];
}
}
template <class T>
T **matrix<T> ::generatematrix (int rows, int cols){
T **temp = new int*[rows];
for(int i =0; i< rows; i++)
{
temp[i] = new int[cols];
}
return temp;
}
template <class T>
void matrix<T> ::print()
{
for(int i=0;i<rows;i++)
{
for(int j =0; j<cols; j++)
{
std::cout<<mat[i][j]<<" ";
}
cout<<endl;
}
}
template <class T>
void matrix<T>::populatematrix(T *src, T size)
{
if (rows * cols !=size){
cout<<"size of matrix is not equal to size of array"<< endl;
exit(-1);
}
int pos =0;
for(int i=0;i<rows; i++){
for(int j=0;j<cols; j++){
this->mat[i][j]=src[pos++];
}
}
}
template <class T>
void multiply (matrix<T> p, vectorimp<T> v)
{
#pragma omp parallel
int g[3];
for (int i=0;i<3;i++){
g[i]=0;
}
//multiplication.
// clock_t start = clock();
#pragma omp for
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
// std::cout << "I am here "<< (v.vec[i][j])<<std::endl;
g[i] = g[i]+( p.mat[i][j] * v.vec[j]);
}
std::cout << "I am here "<< g[i]<<std::endl;
/* clock_t stop = clock();
printf("Computing time = %0.9fus\n",
double(stop - start)/CLOCKS_PER_SEC);*/
}
}
template class matrix<int>;
vector.h
#pragma once
#include <iostream>
#include<vector>
#include <time.h>
#include <ostream>
#include "Matrix_Vector_Multiplication.h"
template <typename T>
class matrix;
template <typename T>
class vectorimp
{
private:
int vec[3];
T vec3D[3][3];
T size;
T recent;
public:
//Default constructor
vectorimp();
// Destructor
~vectorimp();
// function to get assign desired values to the vector
void populate_vector1D(std::vector <std::vector<T> > &data);
template<class T>
friend void multiply(matrix<T> p, vectorimp<T> v);
};
vector.cpp
#include "Vector.h"
#include <iostream>
using namespace std;
template <class T>
vectorimp<T>::vectorimp(){
//vec = vec[4][4];
size = 1;
recent =0;
}
template <class T>
vectorimp<T>::~vectorimp(){}
template <class T>
void vectorimp<T>::populate_vector1D(std::vector <std::vector<T> > &data)
{
for (unsigned int i = 0; i < data.size(); i++)
{ // printing the 2D vector.
for (unsigned int j = 0; j < data[i].size(); j++)
{
vec[i] = data[i][j];
}
}
}
template class vectorimp <int>;
main.cpp file
#include "Matrix_Vector_Multiplication.h"
#include <iostream>
#include "Vector.h"
using namespace std;
int main()
{
int srcA[]= {2,4,3,1,5,7,0,2,3};
matrix<int> matA(3,3);
matA.populatematrix (srcA,9);
std::vector<std::vector<int> > v{ { 2,4,3 },
{ 5,1,6 },
{ 6,3,2 } };
vectorimp<int> p;
p.populate_vector1D(v);
multiply(matA,p);
return 0;
}
To be honest I am not an expert in coding so getting confused in using templates. Thanks a lot for help in advance.
Disclaimer:
Checked out the avaiable resources like
https://isocpp.org/wiki/faq/templates#templates-defn-vs-decl
https://stackoverflow.com/questions/1353973/c-template-linking-error
https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file?rq=1
and few more
You are defining multiply(matrix<int>, vectorimp<int>) in a cpp file, which is an independent compilation unit and thus, not seen outside that file. The templates are instantiated when used/needed, but if it is used in a different compilation unit, the compiler hasn't the function body so it is undefined.
You have to put the function body in the header, so the function body is available for all compilation units (cpp files) that need it.
template <class T>
void multiply (matrix<T> p, vectorimp<T> v);
template <typename T>
class matrix
{
public:
friend void multiply<>(matrix<T> p, vectorimp<T> v);
};
template <class T>
void multiply (matrix<T> p, vectorimp<T> v)
{
// whatever
}
You have to declare the friend function before the class matrix and/or class vectorimp, then tell the compiler it is a template function. You can't put the template<class T> in the friend declaration inside the class because it shadows the template parameter, so simply multiply<> (with angles.)
You have other errors, as not creating a coy constructor. multiply function will receive a copy of the matrix and vectorimp parameters; when the function returns the copies will be deleted and when the program ends you will have a double deletion.
If you pass parameters by reference there will by no double deletion.
In matrix::~matrix you have to delete mat to avoid memory leak.
for (int i=0; i < this->cols; i++)
{
delete [] this->mat[i];
}
delete [] this->mat;
You are allocating ints for an unknown type T:
T **temp = new int*[rows];
This should be:
T **temp = new T*[rows];
And you are mixing indexes with the template type:
T rows ;
T cols ;
Those are independent of the parameter type.
If you make those changes it will work without memory leaks:
manuel#desktop:~/projects$ g++ -Wall main.cc -o main -std=c++17 && valgrind --leak-check=full ./main
==16701== Memcheck, a memory error detector
==16701== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16701== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==16701== Command: ./main
==16701==
I am here 36
I am here 47
I am here 18
==16701==
==16701== HEAP SUMMARY:
==16701== in use at exit: 0 bytes in 0 blocks
==16701== total heap usage: 13 allocs, 13 frees, 73,932 bytes allocated
==16701==
==16701== All heap blocks were freed -- no leaks are possible
==16701==
==16701== For counts of detected and suppressed errors, rerun with: -v
==16701== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
There are also lots of hard coded array indexes (value 3) in declarations and loops that will break if there are matrix and/or vector size changes in main.
There are two suggestions I would like to make, first of all, put your header and cpp files together as you are using template, Secondly please look at the following line of code:
vectorimp<T>::~vectorimp(){}
You did nothing in the destructor this is dangerous, try adding in something like delete[] vec, Also from the line above:
vec = vec[4][4];
It looks like you are trying to intialize a 2D vector, but in your declaration:
int vec[3]
Dangerous.....
T vec3D[3][3];
Declaring this guy but you never intialized it with your constructor.
then you called this guy:
vectorimp<int> p;
Which intializes your vec3D to nullptr.
Finally you decided to pass this nullptr object to your method populate1D:
and do the following call:
vec[i] = data[i][j]
Which since vec is nullptr, program breaks.

How can I get rid of the <error-type> type that is appearing in my method template? Both the input to the method and the class are templates

I am getting the error
declaration is incompatible with "void spectrogram<T>::update(<error-type> x)
I don't see any difference between the declaration and the definition of the method, not sure why it is complaining about just this one definition and not the constructor or destructor.
Here is vComplex.hpp
#ifndef VCOMPLEX_H
#define VCOMPLEX_H
template <class T>
class vComplex {
public:
T* realp;
T* imagp;
int length; // for bookkeeping
vComplex(void) { }
vComplex (T* I, T* Q, int len) {
realp = I;
imagp = Q;
length = len;
}
~vComplex(void) {
free(realp);
free(imagp);
}
void put(T* I, T*Q, int len) {
realp = I;
imagp = Q;
length = len;
}
};
#endif
the function declaration for update in spectrogram.hpp, with other members removed:
#ifndef SPECTROGRAM_H
#define SPECTROGRAM_H
template <typename T>
class spectrogram {
public:
void update(vComplex<T> x);
};
#endif
and the function signature (and includes) for update in spectrogram.cpp:
#include <stdio.h>
#include <math.h>
#include "spectrogram.hpp"
#include "vComplex.hpp"
template <typename T>
void spectrogram<T>::update(vComplex<T> x) {
//do stuff
}
In VS 2017, I get the red underline under update and everything inside of it breaks basically. VS is saying T is undefined which I'm assuming is caused by the overall error. I have to use dynamically allocated pointers, I don't have the option of using other types or containers.

System.AccessViolationException Attempted to read or write protected memory

Hi im working on a program that uses an array of linked lists but im having trouble running it. I keep getting this error and I cannot find a way to fix it. Im only going to include parts of the code that way everything isnt too cluttered. The error message is saying that lines 112 in NodeADT.h, line 141 in MultiListADT.h and line 21 in main.cpp are the ones throwing the error. Ill highlight those lines to make it easier.
Main.cpp
#include <iostream>
#include "MultiListADT.h"
#include <fstream>
#include <string>
using namespace std;
void main(void)
{
MultiListADT<string,100> myList;
string item;
ifstream data;
string input;
int x=0;
data.open("input.txt");
while (!data.eof())
{
getline(data,input);
myList.AddToFront(input); //This is line 21
}
cout << myList << endl;
system("pause");
}
MultiListADT.h
#include <iostream>
#include <fstream>
#include "NodeADT.h"
#include <string>
using namespace std;
template <class TYPE,int threads>
class MultiListADT
{
public:
/** Constructor **/
MultiListADT();
/** Destructor **/
~MultiListADT();
/** Declare accessors (observers) **/
void ResetListForward(int=0);
void ResetListBackward(int=0);
bool IsEmpty(int=0);
int LengthIs(int=0);
bool Search(string, bool=true,int=0);
void GetNextItem(TYPE &,int i=0);
void GetPreviousItem(TYPE &,int=0);
int GetInfo(int=0);
friend ostream& operator << (ostream&, MultiListADT<TYPE, 100>&);
/** Declare mutators (transformers) **/
void MakeEmpty();
void AddToFront(TYPE);
void AddToRear(TYPE);
void InsertInOrder(TYPE);
void Delete(TYPE);
void Sort();
private:
NodeADT<TYPE,threads>* head[threads];
NodeADT<TYPE,threads>* tail[threads];
int length;
string indices[threads];
NodeADT<TYPE,threads>* currentNode[threads];
};
template <class TYPE,int threads>
MultiListADT<TYPE,threads>::MultiListADT()
{
head[threads] = new NodeADT<string,threads>();
tail[threads] = new NodeADT<string,threads>();
head[threads]->setNext(tail[threads]);
tail[threads]->setPrevious(head[threads]);
length = 0;
}
template <class TYPE,int threads>
void MultiListADT<TYPE,threads>::AddToFront(TYPE item)
{
head[0]->AddToFront(item); //This is line 141
length++;
}
NoteADT.h
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const int null = 0;
template<class TYPE, int threads>
class MultiListADT;
template <class TYPE, int threads>
class NodeADT
{
public:
NodeADT();
NodeADT(TYPE);
~NodeADT();
TYPE getInfo();
NodeADT<TYPE, threads>* getPrevious(int=0);
NodeADT<TYPE, threads>* getNext(int=0);
void setNext(NodeADT<TYPE, threads>*,int=0);
void setPrevious(NodeADT<TYPE, threads>*,int=0);
bool Search(TYPE, bool=true,int=0);
void AddToFront(TYPE item);
void AddToRear(TYPE item);
void InsertInOrder(TYPE);
bool Delete(TYPE);
friend ostream& operator << (ostream&, MultiListADT<TYPE, threads>&);
private:
TYPE info;
NodeADT<TYPE, threads>* prev[threads];
NodeADT<TYPE, threads>* next[threads];
};
template <class TYPE,int threads>
NodeADT<TYPE,threads>::NodeADT()
{
prev[threads] = null;
next[threads] = null;
}
template <class TYPE,int threads>
NodeADT<TYPE,threads>::NodeADT(TYPE item)
{
info = item;
prev = null;
next = null;
}
template <class TYPE,int threads>
void NodeADT<TYPE,threads>::AddToFront(TYPE item)
{
NodeADT<TYPE,threads> *temp = new NodeADT<TYPE,threads>;
temp->info = item;
temp->prev[0] = this;
temp->next[0] = next[0];
next[0]->prev[0] = temp; //This is line 112
next[0] = temp;
}
What do YOU think the error means?
On line 112, where do the values for next, prev and temp come from and what are they set to when it crashes? Knowing the values, why do you think it crashed?
Also in one of your NodeADT constructors you assign null to the last element of the array. Or so it appears.
Question: What happens when you assign a value to the element numbered 100 in an array of 100 elements, when element counting starts at 0?
I think the answer, which Zan Lynx has implied, is that you are using threads as an index into your arrays in the constructor of MultiListADT. In AddToFront you use 0 as the index, but that element in the array has never been initialised.

Invalid use of template-name ‘Matrix’ without an argument list

Here is my Matrix.cpp file. (there's a separate Matrix.h file)
#include <iostream>
#include <stdexcept>
#include "Matrix.h"
using namespace std;
Matrix::Matrix<T>(int r, int c, T fill = 1)
{
if (r > maxLength || c > maxLength) {
cerr << "Number of rows and columns should not exceed " << maxLen << endl;
throw 1;
}
if (r < 0 || c < 0) {
cerr << "The values for the number of rows and columns should be positive" << endl;
throw 2;
}
rows = r;
cols = c;
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
mat[i][j] = fill;
}
This gives the following
error: invalid use of template-name ‘Matrix’ without an argument list
What's the problem in my code?
EDIT: The class Matrix is defined with a template<class T>
EDIT:
Here's my Matrix.h file:
#include <iostream>
#include <math.h>
#define maxLength 10;
using namespace std;
template <class T>
class Matrix
{
public:
Matrix(int r, int c, T fill = 1);
private:
int rows, cols;
T mat[10][10];
};
And here's the Matrix.cpp file:
#include <iostream>
#include <stdexcept>
#include "Matrix.h"
using namespace std;
template<class T>
Matrix<T>::Matrix(int r, int c, T fill = 1)
{
}
This gives the following error:
Matrix.cpp:12:43: error: default argument given for parameter 3 of
‘Matrix::Matrix(int, int, T)’ Matrix.h:16:3: error: after previous
specification in ‘Matrix::Matrix(int, int, T)’
What is wrong in my code?
If your class is template then correct definition should be,
template<class T>
Matrix<T>::Matrix(int r, int c, T fill) // don't give default argument
...
Also, don't forget to include this Cpp file where you use this class. Because in the case of templates, full body should be visible to all translation units.
Edit: After your edited question, I noticed that the error says it all.
You are not suppose to give the default argument inside the definition of the method. It's adequate to give in the declaration(which you already gave). Make your template definition as shown above and the error shall disappear.
You should write as:
template<class T>
Matrix<T>::Matrix(int r, int c, T fill = 1)
{
..
}
Yes, it's tedious. And it might not be a good idea to put
the template definitions in the source file, refer to
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12
So the easiest way is to put the definitions of the template members
inside the class template definition in header file.

"undefined reference" to a template class function

I am writing a template class for an array of objects, call it arrayobjclass, which holds pointers to other objects, specifically to other arrays in my implementation. The arrays are implemented as objects as well, call them arrayclass.
Looking for compilation ready with minimal changes.
when I try to test my classes with the following line,
g++ main.cpp arrayclass.cpp arrayobjclass.cpp -o arrayobj
I get the following error:
/tmp/ccEpROXj.o(.text+0x17c): In function `main':
: undefined reference to `arrayobjclass<arrayclass, int>::arrayobjclass(int)'
/tmp/ccEpROXj.o(.text+0x1dc): In function `main':
: undefined reference to `arrayobjclass<arrayclass, int>::addelem(arrayclass*)'
collect2: ld returned 1 exit status
I really can't understand what is wrong. any help would be appreciated. the short relevant part of the code is below if it helps. THANKS IN ADVANCE!
This is what i have in main:
#include "arrayclass.h"
#include "arrayobjclass.h"
#include <iostream>
// 5 arrays of 10 maxsize each
#define MAXSIZE_array 10
#define NUMB_objs 5
using namespace std;
int main () {
//create a simple array as an arrayclass object
arrayclass * numbers1 = new arrayclass (MAXSIZE_array);
//array of objects to hold pointers to simple arrays as created above
arrayobjclass<arrayclass,int> * myobjs = new arrayobjclass<arrayclass,int> (NUMB_objs);
//fill up the simple array
int i;
for (i=0; i<10; i++) {
numbers1->addelem(i);
}
//add a pointer to the simple array in my array of objects
myobjs->addelem(numbers1);
}
//arrayobjclass.h
//declarations of an array of pointers to objects
template <class obj, class key>
class arrayobjclass {
private:
//obj * arrayptr;
obj * objarray [];
int maxsize;
int totalelem;
public:
arrayobjclass(int);
bool addelem(obj *);
};
//arrayobjclass.cpp
//implementation of arrayobjclass, array of pointers to objects
#include "arrayobjclass.h"
#include "arrayclass.h"
template <class obj,class key>
arrayobjclass<obj,key>::arrayobjclass (int size){
maxsize=size;
objarray = new obj[maxsize];
totalelem = 0;
}
template <class obj, class key>
bool arrayobjclass<obj,key>::addelem (obj * newobj) {
if (totalelem < maxsize ) {
objarray[totalelem] = newobj;
totalelem ++;
return true;
}
return false;
}
//arrayclass.h
class arrayclass {
private:
int * arrayptr;
int maxsize;
int totalelem;
public:
arrayclass(int);
bool addelem(int);
};
//arrayclass.cpp
#include "arrayclass.h"
arrayclass::arrayclass (int size){
maxsize=size;
arrayptr = new int[maxsize];
totalelem = 0;
}
bool arrayclass::addelem (int addval) {
if (totalelem < maxsize ) {
arrayptr[totalelem] = addval;
totalelem ++;
return true;
}
return false;
}
You can't put template declarations in .cpp files like that. Template declarations and implementation need to be visible in the same translation unit. Put template implementations in headers that you #include directly.
Define your function templates in the header. Compiler needs to see them.
Cheers & hth.,
Because templates are compiled when required, this forces a
restriction for multi-file projects: the implementation (definition)
of a template class or function must be in the same file as its
declaration. That means that we cannot separate the interface in a
separate header file, and that we must include both interface and
implementation in any file that uses the templates.
From http://www.cplusplus.com/doc/tutorial/templates/
For anyone passing by
you can also #include the implementation files in main
in main:
#include "arrayobjclass.h"
#include "arrayclass.h"
#include "arrayobjclass.cpp"
#include "arrayclass.cpp"