Class Templates

Ok so I understand how function templates work. I am having issues trying to make a class template. I have three separate files, all in the same project, I am using Visual Studios 2010.There is a header file, an implementation file, and the main file. Here is what I have so far, but I get an error message.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//Header File
#ifndef RECTANGLE_H
#define RECTANGLE_H

template <class T>
class Rectangle
{
	private:
		//T width;
		//T length;

	public:
		Rectangle();
		/*
		Rectangle(T, T);

		
		void setLength(T);
		
		void setWidth(T);

		//template <class T>
		T getLength() const
		{	return length;	}

		//template <class T>
		T getWidth() const
		{	return width;	}
		*/
};
#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//implementation file
#include"Rectangle.h"
#include<iostream>
using namespace std;

template<class T>
Rectangle<T>::Rectangle()
{
	cout<<"Hello";
}

/*template<class T>
Rectangle<T>::Rectangle(T l, T w)
{
	length = l;
	width = w;
}


template<class T>
void Rectangle<T>::setLength(T l)
{
	length = l;
}

template<class T>
Rectangle<T>::setWidth(T w)
{
	width = w;
}
*/


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Testing Rectangle.h
#include "Rectangle.h"
#include <iostream>
using namespace std;


int main()
{
	Rectangle<int> r1;
	
	//r1.setLength(5);
	//cout<<"Length: ";
	//r1.getLength();

	return 0;
}


I get the following errors:
error C2995: 'Rectangle<T>::Rectangle(void)' : function template has already been defined
: see declaration of 'Rectangle<T>::Rectangle'

As you can see I cannot even create an instance of the Rectangle<T> class
On a side note, I completely commented out the .cpp file. Then in the header file I assigned width and length 0 in the default constructor. I uncommented the getLength and getWidth functions, but when I called them they did not return anything. So this leads me to believe that when using class templates, you cannot have a .cpp file. Is this correct?
Yes. For templates, the implementation and declaration must be in the same file.
Ok so now my updated code is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//Header File
#ifndef RECTANGLE_H
#define RECTANGLE_H

template <class T>
class Rectangle
{
	private:
		T width;
		T length;

	public:
		Rectangle()
		{
			length = 5;
			width = 0;
		}

		T getLength() const
		{	return length;	}
		
};
#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "Rectangle.h"
#include <iostream>
using namespace std;


int main()
{
	Rectangle<int> r1;
	
	//r1.setLength(5);
	cout<<"Length: ";
	r1.getLength();

	return 0;
}


And it returns nothing. I get:

Length:
And it returns nothing
It returns length correctly.

You got what you output: cout<<"Length: ";. You did not output anything else, so you did not get anything else on screen.
When I create a Rectangle object, the member variables, length and width, are assigned default values in the default constructor. But since the member variables are of type T, assigning them 5, and 0, is wrong. Am I correct in this?

Also, Ive been messing around with it, and my getLength() function is not returning anything. Either the member variables of Rectangle are not being set, or the getLength() function is not working properly. For example, my code is now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef RECTANGLE_H
#define RECTANGLE_H

template <class T>
class Rectangle
{
	private:
		T width;
		T length;

	public:
		
		Rectangle()
		{
			length = 5;
			width = 0;
		}

		void setLength(T l)
		{
			length = l;			
		}
		
		T getLength() const
		{	return length;	}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "Rectangle.h"
#include <iostream>
using namespace std;


int main()
{
	Rectangle<int> r1;
	
	r1.setLength(5);
	cout<<"Length: ";
	r1.getLength();

	return 0;
}


For output, I still get:

Length:
But since the member variables are of type T, assigning them 5, and 0, is wrong. Am I correct in this?
As T is probably is going to be Arithmetic (there is no sense in having Rectangle<string> for example), it should be fine. You might want to do
length = T(5); instead.

and my getLength() function is not returning anything.
It is correctly returning value of length.
Do a simple check: replace r1.getLength(); on line 12 with 5.
Do you see that 5 outputted? No? Do you know why is it? Because you are not outputting it.
Wow im an idiot! Ok getLength() was returning a value, but it was not being stored anywhere! Okay lol.

Why do:
length = T(5)?
Some object might have explicit constuctor taking int, so implicit conversion might be disabled.

Actually completely correct way to initialize would be to use constructor initializer list:
1
2
Rectangle() : length(5), width(0) 
{}
Topic archived. No new replies allowed.