Reputation: 31
I cannot compile... I have no idea what's wrong here... This is where the errors occur:
void MainThread::run()
{
Set<int>* p_test; p_test = new Set<int>;
p_test->add(new int(9));
std::cout<<"The set is: {";
for (int x = 0; x < p_test->size(); x++)
std::cout<< ", " << p_test->toString(x).toStdString().c_str();
std::cout<<"}";
std::cin.get();
}//test method
The error message is given as: "undefined reference to Set::Set()" and it shows up on the line that I try to use my class. My class compiles on its own... Below is the file "Set.h". Anybody have any idea as to how I can fix it? Thanks in advance.
#ifndef SET_H
#define SET_H
#include <functional>
#include <QList>
#include <QString>
#include <type_traits>
#include <exception>
#include <iostream>
template<typename T>
class Set {
public:
//constructors
Set();
~Set(){ delete []pType; }
//functions
const int & size(){ return m_size; }
void add(const T * singleton);
void empty();
//operators
inline T& operator [](int index){ return pType[index]; }
template<class Y>
friend Set<Y> operator *(const Set<Y>& s1, const Set<Y>& s2);//intersection
template<class Y>
friend Set<Y> operator *(Set<Y>& s1, Set<Y>& s2);
template<class Y>
friend Set<Y> operator +(const Set& s1, const Set& s2);//union
template<class Y>
friend Set operator -(const Set& s1, const Set& s2);//relative complement
bool operator =(const Set& other)
{
delete []pType;//empty out the array
/** Gets operator **/
int x = other.size();
pType = new T[x];
for (int y = 0; y < x; y++)
pType[y] = other[y];
m_size = x;
return true;
}
bool operator ==(const Set & other)
{
if(other.size() != size())
return false;
else
{
for (int x = 0; x < size(); x++)
if (!other.has(pType[x]))
return false;
}//end else
return true;
}//end equals operator
/*template<typename Type>
bool operator *= (const Set<Type> &lhs, const Set<Type> &rhs){
//compile time statement (just to let people know)
static_assert(std::is_same<Type1, Type2>::value, "Types are not equal!");
return std::is_same<Type1, Type2>::value;
}//operator for checking if two things are the same type */
bool operator >(const Set &other)
{ /** Superset **/ return false; }
\
bool operator <(const Set *other)
{ /** Subset **/ return false; }
Set& complement();
bool isEmpty(){ return m_size == 0; }
bool has(T* element);
QString toString(int index);
private:
T * pType;
T * m_Type; //save the variable type.
int m_size;
};
#endif // SET_H
I do have a constructor defined in a separate file.
Set<Y>::Set()
{
m_size = 0;
m_Type = new Y();//save a default value
}//create an empty set
Or do I need a different kind of constructor?
Upvotes: 1
Views: 151
Reputation: 1072
Since you are writing a template class, all methods of the clas must be defined in the header file. Such as
template<typename T>
class Set {
Set() { } // <-- declaration and definition
};
This is because the compiler does not compile templated classes/functions until finds a place in the code that actually uses it, so your class "does not compile on its own".
To compile a template class, the compiler looks for the declaration and for the definition in the same file. Then the compiler will generate code that actually implements the function for the specific templated argument.
So put your function definitions in the same file when working with templates. If you want to create a specialization, then the specialized function is no longer a template and you have to put it in a separated file unless you declarte it inline
.
Sorry if your head hurts after reading all of this... welcome to C++.
Upvotes: 1
Reputation: 98425
Every method of your Set
class must be defined in the header file. Your header file lacks the definition of Set::Set()
, and of some other methods as well.
Upvotes: 2