Page 1 of 1

Making a template - Symbol(s) not found

Posted: Tue Jul 14, 2009 11:48 am
by Sanshin77
Im trying to create my own Array class, just as the book I read did but Im having a weird problem

Header file:

Code: Select all

#ifndef __ARRAY_H__
#define __ARRAY_H__

typedef unsigned short USHORT;
const USHORT DefaultSize = 10;

template <class T>
class saArray
{
public:
	saArray(USHORT size = DefaultSize);
	saArray(const saArray &rhs);
	~saArray(){delete [] pType;}
	
	saArray& operator=(const saArray&);
	T& operator[](USHORT offset);
	const T& operator[](USHORT offset) const {return pType[offset];}
	
	USHORT GetSize(){return Size;}
private:
	T *pType;
	USHORT Size;
};

#endif
Im having some trouble with the constructor, here's the implementation:

Code: Select all

template <class T>
saArray<T>::saArray(USHORT size):
Size(size)
{
	pType = new T[size];
	for(USHORT i = 0; i<size; i++)
		pType[i] = 0;
}
And finally this is what Xcode(Mac) tells me:

Code: Select all

"saArray<unsigned short>::saArray(unsigned short)", referenced from:
_main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Ive figured out two ways to solve this, but they're not ideal, so if someone could explain whats happening and what needs fixing that'd be great.
My first solution is to include the Array.cpp instead of .h .
The other solution is to move the function implementation to the header file.

Thanks in advance
Sanshin

Edit:
This actually applies to all of the functions.

Re: Making a template - Symbol(s) not found

Posted: Tue Jul 14, 2009 1:46 pm
by fantastico
The problem is that the compiler needs to see the actual code of your functions when it instantiates a template, since it has to produce code for that concrete type and can no longer stay on a generic/templated level. Instantiation happens when the compiler sees that you wrote saArray<unsigned short> for example.
However, since only the header files were included, it doesn't know about the actual implementation of the function (the constructor in your case).

One way to get around that is, as you already wrote, to include the cpp file, which is typically done at the end of the header file. I think it is called inclusion compilation if you want to google. Don't forget that you don't have to compile the saArray.cpp file seperately anymore now, because for example if your main.cpp includes the header file, it will already be compiled when compiling main.cpp.

Re: Making a template - Symbol(s) not found

Posted: Tue Jul 14, 2009 2:02 pm
by Sanshin77
Thanks, but could you tell me how to do this, which files should include what?

the .h should include the .cpp , the main should include the .h what about "Array.cpp"?

Should It include the header? Should I add Inclusion Guards to the .cpp ?

Re: Making a template - Symbol(s) not found

Posted: Tue Jul 14, 2009 4:03 pm
by fantastico
Pretty much the same as you would normally do except for that one include and leaving out the cpp file in the compilation process.

Array.h includes Array.cpp at the end of the file, just before the #endif of the guards. You can leave the #include "Array.h" in the Array.cpp file, if your IDE needs it for context sensitive help or something like that but for compilation it isn't required. There's no need for guards in the cpp file, it's already "guarded" by the header file which includes it.

In other code files (like main) you only have to include the header as usual then.

Re: Making a template - Symbol(s) not found

Posted: Fri Jul 17, 2009 8:03 pm
by MarauderIIC
In the way of organization, some people use the practice of naming files that are included in header files as ".inl" (for inline). I've seen it used when they declare a member function header as inline but don't want to pollute their class definition with the function definition. Since the function is inline, it must be included in the header, so adding a #include "myfile.inl" solves the problem. You might consider renaming your myArray.cpp to myArray.inl and #include-ing it in your header, as well.