Template classes and how to use them properly

  • (2 Pages)
  • +
  • 1
  • 2

19 Replies - 2081 Views - Last Post: 08 September 2013 - 05:53 PM Rate Topic: -----

#1 logicaltheory  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 08-September 13

Template classes and how to use them properly

Posted 08 September 2013 - 02:26 PM

Okay, I have been struggling with creating a rectangle class. The problem is to take in a length and a width, as long as length>width, and return the perimeter and area of the rectangle using different datatypes. I have searched google and referred to all of my C++ books, but I can't find an answer as to what I am doing wrong. I think I have a decent understanding of how this is suppose to work, but every time I try something new, I get errors like I have never seen before.

Here is the list of errors that I am receiving with the following code:
...rectanglesource.cpp(33): error C3867: 'Rectangle<T>::setLength': function call missing argument list; use '&Rectangle<T>::setLength' to create a pointer to member
with
[
T=float
]
...rectanglesource.cpp(36): error C3867: 'Rectangle<T>::setWidth': function call missing argument list; use '&Rectangle<T>::setWidth' to create a pointer to member
[
T=float
]
...rectanglesource.cpp(42): error C3867: 'Rectangle<T>::setLength': function call missing argument list; use '&Rectangle<T>::setLength' to create a pointer to member
[
T=int
]
...rectanglesource.cpp(45): error C3867: 'Rectangle<T>::setWidth': function call missing argument list; use '&Rectangle<T>::setWidth' to create a pointer to member
[
T=int
]

What I gather, is that the compiler is telling me that I need to create a pointer, but I'm not sure where and how exactly.

Here is my current code:

rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
template <class T>
class Rectangle
{
public:
	void setLength(T len);
	void setWidth(T wid);
	bool checkSize(T check);
	T getLength();
	T getWidth();
	T getParimeter();
	T getArea();
private:
	T length;
	T width;
	T parimeter;
	T area;
};

#endif


rectangle.cpp
#include "rectangle.h"

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

template <class T>
void Rectangle <T>::setWidth(T wid)
{
	width=wid;
}

template <class T>
bool Rectangle <T>::checkSize(T check)
{
	if (length>width)return true;return false;
}

template <class T>
T Rectangle <T>::getLength()
{
	return length;
}

template <class T>
T Rectangle <T>::getWidth()
{
	return width;
}

template <class T>
T Rectangle <T>::getParimeter()
{
	parimeter=(length*2)+(width*2);
	return parimeter;
}

template <class T>
T Rectangle <T>::getArea()
{
	area=length*width;
	return area;
}


rectangleSource.cpp
#include <iostream>
#include "rectangle.h"
using namespace std;

int main()
{
	Rectangle<float> rectangleFloat;
	Rectangle<int> rectangleInt;
	int input=0;
	
	cout<<"This program is used to set the length and width\n";
	cout<<"of a rectangle using either float or int as the DataType,\n";
	cout<<"where the length must be greater than the width.\n\n";
	// Menu
	while (input !=5)
	{
		cout<<"(1) Enter the size of the rectangle using DataType float\n";
		cout<<"(2) Enter the side of the rectangle using DataType int\n";
		cout<<"(3) Display length, width, parimeter, and area of the \"float\"";
		cout<<" rectangle\n";
		cout<<"(4) Display length, width, parimeter, and area of the \"int\"";
		cout<<" rectangle\n";
		cout<<"(5) Exit the program\n\n";
		cin>>input;
		cout<<"\n";

		switch(input)
		{
		case 1:
			float len, wid;
			cout<<"Enter the length of the rectangle: ";
			cin>>len;
			rectangleFloat.setLength;
			cout<<"Enter the width of the rectangle: ";
			cin>>wid;
			rectangleFloat.setWidth;
		break;
		case 2:
			int Flen, Fwid;
			cout<<"Enter the length of the rectangle: ";
			cin>>Flen;
			rectangleInt.setLength;
			cout<<"Enter the width of the rectangle: ";
			cin>>Fwid;
			rectangleInt.setWidth;
			break;
		case 3:
			cout<<"The length of the \"float\" rectangle is ";
			cout<<rectangleFloat.getLength();
			cout<<"\nThe width of the \"float\" rectangle is ";
			cout<<rectangleFloat.getWidth();
			cout<<"\nThe parimeter of the \"float\" rectangle is ";
			cout<<rectangleFloat.getParimeter();
			cout<<"\nThe area of the \"float\" rectangle is ";
			cout<<rectangleFloat.getArea();
			cout<<"\n\n";
			break;
		case 4:
			cout<<"The length of the \"int\" rectangle is ";
			cout<<rectangleInt.getLength();
			cout<<"\nThe width of the \"int\" rectangle is ";
			cout<<rectangleInt.getWidth();
			cout<<"\nThe parimeter of the \"int\" rectangle is ";
			cout<<rectangleInt.getParimeter();
			cout<<"\nThe area of the \"int\" rectangle is ";
			cout<<rectangleInt.getArea();
			cout<<"\n\n";
			break;
		case 5:
			cout<<"The program will now exit\n\n";
			cin.get();
		}
		
	}
	system("pause");
};


I understand that this might not be the most efficient code, but I am learning. I know I have a long way to go, but I am about to pull my hair out over this one. I know it's probably easier that I am making out, but I am so confused, and burnt out right now.

Is This A Good Question/Topic? 0
  • +

Replies To: Template classes and how to use them properly

#2 vividexstance  Icon User is offline

  • Tiocfaidh ár lá
  • member icon

Reputation: 792
  • View blog
  • Posts: 2,873
  • Joined: 31-December 10

Re: Template classes and how to use them properly

Posted 08 September 2013 - 02:47 PM

I think the best way to move forward would be to define a Rectangle class that just uses a scalar data type for the length of the sides, probably an int. Get that working and test it thoroughly. Once you are sure it's working properly, then change the class to use templates. A simple find+replace in a text editor could do most of the work.

*EDIT*:
Most compiler require the implementation of the template class to be entirely inside the header. That's most likely the errors you are receiving.

This post has been edited by vividexstance: 08 September 2013 - 02:48 PM

Was This Post Helpful? 1
  • +
  • -

#3 logicaltheory  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 08-September 13

Re: Template classes and how to use them properly

Posted 08 September 2013 - 02:52 PM

View Postvividexstance, on 08 September 2013 - 02:47 PM, said:

I think the best way to move forward would be to define a Rectangle class that just uses a scalar data type for the length of the sides, probably an int. Get that working and test it thoroughly. Once you are sure it's working properly, then change the class to use templates. A simple find+replace in a text editor could do most of the work.

*EDIT*:
Most compiler require the implementation of the template class to be entirely inside the header. That's most likely the errors you are receiving.



So you are saying that instead of having a rectangle.cpp file, just have whats in rectangle.h and rectangle.cpp combined in the rectangle.h file?

Also, I am going to start building a new solution with an int datatype, then move on, like you said.

Thanks for the assistance.

Logicaltheory
Was This Post Helpful? 0
  • +
  • -

#4 salazar  Icon User is offline

  • D.I.C Addict

Reputation: 105
  • View blog
  • Posts: 648
  • Joined: 26-June 13

Re: Template classes and how to use them properly

Posted 08 September 2013 - 02:55 PM

There's nothing wrong with your use of templates. The problem is in the way you call your set functions.

		case 1:
			float len, wid;
			cout<<"Enter the length of the rectangle: ";
			cin>>len;
			rectangleFloat.setLength;
			cout<<"Enter the width of the rectangle: ";
			cin>>wid;
			rectangleFloat.setWidth;
		break;
		case 2:
			int Flen, Fwid;
			cout<<"Enter the length of the rectangle: ";
			cin>>Flen;
			rectangleInt.setLength;
			cout<<"Enter the width of the rectangle: ";
			cin>>Fwid;
			rectangleInt.setWidth;
			break;



It should be setLength(len), setWidth(wid), ... etc. As an aside, I think you have your variables mixed up. Shouldn't Flen and Fwid be floats rather than ints.

This post has been edited by salazar: 08 September 2013 - 02:58 PM

Was This Post Helpful? 2
  • +
  • -

#5 vividexstance  Icon User is offline

  • Tiocfaidh ár lá
  • member icon

Reputation: 792
  • View blog
  • Posts: 2,873
  • Joined: 31-December 10

Re: Template classes and how to use them properly

Posted 08 September 2013 - 03:00 PM

He does have it mixed up in the switch-statement, case 1 is for integers and case 2 is for floating-point, according to the prompt anyways.
Was This Post Helpful? 1
  • +
  • -

#6 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2603
  • View blog
  • Posts: 4,157
  • Joined: 21-June 11

Re: Template classes and how to use them properly

Posted 08 September 2013 - 03:01 PM

To call a member function you need to write name_of_the_object.name_of_the_function(arguments). You just wrote name_of_the_object.name_of_the_function. The compiler is telling you that you forgot the argument list and that, if your intent was to create a pointer to the function (which it wasn't), you should have used &. Since your intent was not to create a function pointer, you can just ignore that last part. You need to add an argument list.
Was This Post Helpful? 1
  • +
  • -

#7 logicaltheory  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 08-September 13

Re: Template classes and how to use them properly

Posted 08 September 2013 - 03:08 PM

Alright, its a lot to keep in my head all at once. I think I am beginning to better understand what is going on. Of course, once I get all of my arguments smoothed out, I have to make sure not to confuse all of the instances like vividexstance pointed out. I'm still going to start from the beginning with an int class, then change it to a template, but I see where I made some mistakes the first time around.

Thank you vividexstance, salazar, and sepp2k!

I'll check back in once I get this go-round compiling better.
Was This Post Helpful? 0
  • +
  • -

#8 vividexstance  Icon User is offline

  • Tiocfaidh ár lá
  • member icon

Reputation: 792
  • View blog
  • Posts: 2,873
  • Joined: 31-December 10

Re: Template classes and how to use them properly

Posted 08 September 2013 - 03:14 PM

Your welcome, just remember to hit the Posted Image button at the bottom right of each post if it's helpful.
Was This Post Helpful? 1
  • +
  • -

#9 jimblumberg  Icon User is online

  • member icon

Reputation: 5467
  • View blog
  • Posts: 17,019
  • Joined: 25-December 09

Re: Template classes and how to use them properly

Posted 08 September 2013 - 03:26 PM

And remember with templates both the declaration and the implementation must be in the same compilation unit. This usually leads to header only implementations.

Jim
Was This Post Helpful? 1
  • +
  • -

#10 logicaltheory  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 08-September 13

Re: Template classes and how to use them properly

Posted 08 September 2013 - 04:57 PM

Okay, now I am having "error LNK2019: unresolved external symbol" issues. I don't know what I am doing wrong. Should I post the new code? Or maybe start a new thread. I am getting nowhere by searching. I am so confused.
Was This Post Helpful? 0
  • +
  • -

#11 vividexstance  Icon User is offline

  • Tiocfaidh ár lá
  • member icon

Reputation: 792
  • View blog
  • Posts: 2,873
  • Joined: 31-December 10

Re: Template classes and how to use them properly

Posted 08 September 2013 - 05:01 PM

Post an exact copy of the error message because it usually contains vital information. Posting the new code can help as well.

This post has been edited by vividexstance: 08 September 2013 - 05:01 PM

Was This Post Helpful? 1
  • +
  • -

#12 logicaltheory  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 08-September 13

Re: Template classes and how to use them properly

Posted 08 September 2013 - 05:06 PM

okay, I got the thing to compile by using only the *.h and source.cpp files. the problem I have is that the assignment calls for it to be split up in three files like I originally had it, but whenever I do that I get linker errors.

I will split the files up into the 3 required files, recompile and post everything. AHHH. Thank you so much for your assistance and patience.

will post shortly.
Was This Post Helpful? 0
  • +
  • -

#13 logicaltheory  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 08-September 13

Re: Template classes and how to use them properly

Posted 08 September 2013 - 05:12 PM

rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H

template <class T>
class Rectangle
{
public:
	Rectangle();
	void setLength(T l);
	void setWidth(T w);
	T getLength();
	T getWidth();
	T getPerimeter();
	T getArea();
private:
	T length;
	T width;
	T perimeter;
	T area;
};

#endif



rectangle.cpp
#include "rectangle.h"

template <class T>
Rectangle<T>::Rectangle()
{
}

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

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

template <class T>
T Rectangle<T>::getLength()
{
	return length;
}

template <class T>
T Rectangle<T>::getWidth()
{
	return width;
}

template <class T>
T Rectangle<T>::getPerimeter()
{
	perimeter=(length*2)+(width*2);
	return perimeter;
}

template <class T>
T Rectangle<T>::getArea()
{
	area=length*width;
	return area;
}



rectangleSource.cpp
#include "rectangle.h"
#include <iostream>
using namespace std;

int main()
{
	Rectangle<float> rectangleF;
	Rectangle<int> rectangleI;
	int input=0;

	cout<<"This program is used to set the length and width\n";
	cout<<"of a rectangle using either float or int as the DataType.\n\n";

	while (input !=5)
	{
		cout<<"(1) Enter the size of the rectangle using DataType float\n";
		cout<<"(2) Enter the size of the rectangle using DataType int\n";
		cout<<"(3) Display the length, width, perimeter, and area of ";
		cout<<"the \"float\" rectangle\n";
		cout<<"(4) Display the length, width, perimeter, and area of ";
		cout<<"the \"int\" rectangle\n";
		cout<<"(5) Exit the program\n";
		cin>>input;
		cout<<"\n";

		switch(input)
		{
		case 1:
			float fL, fW;
			cout<<"Enter the length of the rectangle: ";
			cin>>fL;
			rectangleF.setLength(fL);
			cout<<"Enter the width of the rectangle: ";
			cin>>fW;
			rectangleF.setWidth(fW);
		break;
		case 2:
			int iL, iW;
			cout<<"Enter the length of the rectangle: ";
			cin>>iL;
			rectangleI.setLength(iL);
			cout<<"Enter the width of the rectangle: ";
			cin>>iW;
			rectangleI.setWidth(iW);
		break;
		case 3:
			cout<<"The length of the \"float\" rectangle is :";
			cout<<rectangleF.getLength()<<endl;
			cout<<"The width of the \"float\" rectangle is :";
			cout<<rectangleF.getWidth()<<endl;
			cout<<"The perimeter of the \"float\" rectangle is :";
			cout<<rectangleF.getPerimeter()<<endl;
			cout<<"The area of the \"float\" rectangle is :";
			cout<<rectangleF.getArea()<<endl<<endl;
		break;
		case 4:
			cout<<"The length of the \"int\" rectangle is :";
			cout<<rectangleI.getLength()<<endl;
			cout<<"The width of the \"int\" rectangle is :";
			cout<<rectangleI.getWidth()<<endl;
			cout<<"The perimeter of the \"int\" rectangle is :";
			cout<<rectangleI.getPerimeter()<<endl;
			cout<<"The area of the \"int\" rectangle is :";
			cout<<rectangleI.getArea()<<endl<<endl;
		break;
		case 5:
			cout<<"The program will now exit\n\n";
			cin.get();
		}
	}

	system("pause");
}



and the errors are:
1>------ Rebuild All started: Project: rectangle, Configuration: Debug Win32 ------
1> rectangleSource.cpp
1> rectangle.cpp
1> Generating Code...
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: __thiscall Rectangle<float>::Rectangle<float>(void)" (??0?$[email protected]@@[email protected]) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: void __thiscall Rectangle<float>::setLength(float)" ([email protected]?$[email protected]@@[email protected]) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: void __thiscall Rectangle<float>::setWidth(float)" ([email protected]?$[email protected]@@[email protected]) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: float __thiscall Rectangle<float>::getLength(void)" ([email protected]?$[email protected]@@QAEMXZ) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: float __thiscall Rectangle<float>::getWidth(void)" ([email protected]?$[email protected]@@QAEMXZ) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: float __thiscall Rectangle<float>::getPerimeter(void)" ([email protected]?$[email protected]@@QAEMXZ) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: float __thiscall Rectangle<float>::getArea(void)" ([email protected]?$[email protected]@@QAEMXZ) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: __thiscall Rectangle<int>::Rectangle<int>(void)" (??0?$[email protected]@@[email protected]) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: void __thiscall Rectangle<int>::setLength(int)" ([email protected]?$[email protected]@@[email protected]) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: void __thiscall Rectangle<int>::setWidth(int)" ([email protected]?$[email protected]@@[email protected]) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: int __thiscall Rectangle<int>::getLength(void)" ([email protected]?$[email protected]@@QAEHXZ) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: int __thiscall Rectangle<int>::getWidth(void)" ([email protected]?$[email protected]@@QAEHXZ) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: int __thiscall Rectangle<int>::getPerimeter(void)" ([email protected]?$[email protected]@@QAEHXZ) referenced in function _main
1>rectangleSource.obj : error LNK2019: unresolved external symbol "public: int __thiscall Rectangle<int>::getArea(void)" ([email protected]?$[email protected]@@QAEHXZ) referenced in function _main
1>C:\Users\Eric\Documents\ownCloud\School\!FAMU\2013\Fall\COP3530\VS Projects\Rectangle1\rectangle\Debug\rectangle.exe : fatal error LNK1120: 14 unresolved externals
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========


I think I am #includ(ing) the files wrong, but I don't see how.

FYI, when I combine the rectangle.h and rectangle.cpp files as one rectangle.h file, it will compile and execute without issue.
Was This Post Helpful? 0
  • +
  • -

#14 vividexstance  Icon User is offline

  • Tiocfaidh ár lá
  • member icon

Reputation: 792
  • View blog
  • Posts: 2,873
  • Joined: 31-December 10

Re: Template classes and how to use them properly

Posted 08 September 2013 - 05:21 PM

Remember that the implementation of the class, the .cpp file, shouldn't even exist. It can all be copied into the header file underneath the class declaration.

Any templates must be totally implemented in the header file.

This post has been edited by vividexstance: 08 September 2013 - 05:22 PM

Was This Post Helpful? 1
  • +
  • -

#15 logicaltheory  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 08-September 13

Re: Template classes and how to use them properly

Posted 08 September 2013 - 05:24 PM

I get that, but for some reason my instructor is telling us that it is the other way around. It doesn't make sense to me, but the way he wants it is class definition in the *.h file, implementation in the *.cpp file, then of course the main will be in the *Source.cpp file. Is it possible to do it his way?
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2