Thread: Having a problem with templates and classes

  1. #1
    Registered User
    Join Date
    May 2007
    Posts
    12

    Having a problem with templates and classes

    here is my code:
    Code:
    /*===========================================[ REDEFINITION DEFENCE ]=======*/
    #ifndef AutoArrayPtr_H
    #define AutoArrayPtr_H
    
    /*===========================================[ PUBLIC TYPES ]===============*/
    
    template<class X>
    class auto_array_ptr;
    
    #define ASSERT(a)
    #define ASSERT_EX_H(a)
    
    // must be in GFL namespace
    
    template<class T>
    void fill(auto_array_ptr<T>& pa, BYTE byFill)
    {
    	ASSERT(pa.m_Pointee); // no ex
    
    	if(pa.m_Pointee && pa.m_size > 0)
    	{
    		::FillMemory(pa.m_Pointee, pa.sizeInBytes(), byFill);
    	}
    }
    
    template<class T>
    void copy(auto_array_ptr<T>& pa, const void* pBuffer, size_t size)
    {
    	ASSERT_EX_H(pa.m_Pointee);
    
    	ASSERT_EX_H(pBuffer);
    	ASSERT_EX_H(size > 0);
    	ASSERT_EX_H(size <= pa.sizeInBytes());
    
    	::CopyMemory(pa.m_Pointee, pBuffer, size);
    }
    
    template<class T>
    void zero(auto_array_ptr<T>& pa)
    {
    	fill(pa, 0);
    }
    
    // truly free all the memory, capacity is 0
    template<class T>
    void freeEx(auto_array_ptr<T>& pa)
    {
    	delete [] pa.m_Pointee;
    	pa.m_Pointee  = NULL;
    	pa.m_size     = 0;
    	pa.m_capacity = 0;
    }
    
    
    //  auto_array_ptr
    //  -------------------
    // checks the size and overrides
    // DO NOT USE IT FOR AN ARRAY OF OBJECTS WHICH constructors need to be 
    // called!!
    // Need to use VC 7.0 and full Loki library to check this condition
    // at compile time.
    
    template<class X>
    class auto_array_ptr
    {
    	friend void fill(auto_array_ptr<X>& pa, BYTE byFill);
    
    	friend void copy(auto_array_ptr<X>& pa, const void* pBuffer, size_t size);
    
    	friend void freeEx(auto_array_ptr<X>& pa);
    
      public:
    
    		explicit auto_array_ptr(size_t size = 0, BYTE byFillWith = 0)
    		{
    			m_size         = 0;
    			m_capacity     = 0;
    			m_Pointee      = NULL;
    
    			if(size > 0)
    			{
    				m_Pointee  = new X[size];
    				m_size     = size;
    				m_capacity = size;
    
    				fill(*this, byFillWith);
    			}
    		}
    
    		template<class Y>
    		auto_array_ptr(const auto_array_ptr<Y>& r)
    		{
    			m_size         = r.size    ();
    			m_capacity     = r.capacity();
    			m_Pointee      = r.release ();
    		}
    
    		~auto_array_ptr()
    		{
    			freeEx(*this);
    		}
    
    		template<class Y>
    		auto_array_ptr& operator = (auto_array_ptr<Y>& r)
    		{
    			if(static_cast<void*>(&r) != static_cast<void*>(this))
    			{
    				freeEx(*this);
    
    				m_size         = r.size();
    				m_capacity     = r.capacity();
    				m_Pointee      = r.release();
    			}
    
    			return *this;
    		}
    
    		// MS compiler doesn't generate this method from the template
    		// sppecified above, so let's hard-code it
    		auto_array_ptr& operator = (auto_array_ptr& r)
    		{
    			if((void*)&r != (void*)this)
    			{
    				freeEx(*this);
    
    				m_size         = r.size();
    				m_capacity     = r.capacity();
    				m_Pointee      = r.release();
    			}
    
    			return *this;
    		}
    
    		// note, it reallocates the buffer ONLY if the requested
    		// size is bigger than the current one
    		void reset(size_t size = 0, BYTE byFillWith = 0, bool bFill = true)
    		{
    			bool bSizeWasChanged = m_size != size;
    
    			if(m_size < size)
    			{
    				freeEx(*this);
    
    				ASSERT(size > 0);
    
    				m_Pointee  = new X[size];
    				m_capacity = size;
    
    				m_size = size;
    
    				// do not do anything if size stays the same
    				if(bFill)
    					fill(*this, byFillWith);
    			}
    			else
    			if(m_size > size)
    			{
    				// new size is smaller than m_size
    				// m_capacity is used instead of m_size, because
    				// not all calls to reset might have been done with bFill == true
    				size_t delta = m_capacity - size;
    
    				// clean up unused part of the buffer
    				if(bFill && m_Pointee && delta > 0)
    				{
    					::FillMemory(
    						m_Pointee + m_capacity - delta,
    						delta * sizeof(X),
    						byFillWith);
    				}
    
    				m_size = size;
    			}
    
    			// same size do not do anything
    		}
    
    		X& operator*()  const
    		{
    			return *m_Pointee;
    		}
    
    		// used to check auto ptrs for null
    		bool operator ! () const
    		{
    			return m_Pointee == NULL;
    		}
    
    		template<class Index>
    		const X& operator [] (Index index) const
    		{
    			ASSERT(index < m_size);
    			return m_Pointee[index];
    		}
    
    		template<class Index>
    		X& operator [] (Index index)
    		{
    			ASSERT(index < m_size);
    			return m_Pointee[index];
    		}
    
    		const X* get() const
    		{
    			return m_Pointee;
    		}
    
    		X* get()
    		{
    			return m_Pointee;
    		}
    
    		size_t size() const
    		{
    			return m_size;
    		}
    
    		size_t sizeInBytes() const
    		{
    			return m_size * sizeof(X);
    		}
    
    		size_t capacity() const
    		{
    			return m_capacity;
    		}
    
    		size_t capacityInBytes() const
    		{
    			return m_capacity * sizeof(X);
    		}
    
    		X* release()
    		{
    			X* Pointee = m_Pointee;
    
    			m_Pointee = 0;
    			m_size    = 0;
    			capacity  = 0;
    
    			return Pointee;
    		}
    
      private:
    
    			size_t          m_size    ; // size in elements of X type
    			size_t          m_capacity; // actual size of the buffer m_size <= m_capacity
    			X*              m_Pointee ;
    
    };
    
    /*===========================================[ END REDEFINITION DEFENCE ]===*/
    #endif/*AutoArrayPtr_H*/
    
    /** (END OF FILE  : AutoArrayPtr.h) *********************************************/
    Why do i keep getting linker Errors even though the functions are defined?

  2. #2
    Registered User
    Join Date
    May 2007
    Posts
    12
    Here are the errors i get:

    [Linker error] undefined reference to `freeEx(auto_array_ptr<double>&)'
    [Linker error] undefined reference to `fill(auto_array_ptr<double>&, unsigned char)'

    i get about 13 of these. Any help would be appreciated!

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by bowluswj View Post
    Why do i keep getting linker Errors even though the functions are defined?
    What functions? What linker errors? Posting a mess of code and asking "What's wrong" is useless.

  4. #4
    Massively Single Player AverageSoftware's Avatar
    Join Date
    May 2007
    Location
    Buffalo, NY
    Posts
    141
    Friend templates require some unusual declarations.

    This link should help:
    http://www.parashift.com/c++-faq-lit...html#faq-35.16
    There is no greater sign that a computing technology is worthless than the association of the word "solution" with it.

  5. #5
    Registered User
    Join Date
    May 2007
    Posts
    12
    Quote Originally Posted by brewbuck View Post
    What functions? What linker errors? Posting a mess of code and asking "What's wrong" is useless.
    The problem comes from two functions that are located near the top of the code (Fill and FreeEx). Both are template functions that are used in the template class that follows. Those two functions are defined, yet i get a linker error when i compile this with my main code. If i am still unclear, i will attempt to explain it better.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Questions about Templates
    By Shamino in forum C++ Programming
    Replies: 4
    Last Post: 12-18-2005, 12:22 AM
  2. templates and inheritance problem
    By kuhnmi in forum C++ Programming
    Replies: 4
    Last Post: 06-14-2004, 02:46 AM
  3. Templates and Inheritance problem
    By WebSnozz in forum C++ Programming
    Replies: 0
    Last Post: 04-11-2004, 02:39 PM
  4. VC++6: exporting classes containing templates
    By ttt in forum Windows Programming
    Replies: 2
    Last Post: 09-15-2003, 11:38 AM