Linker error for constructor and destructor of CList

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • bajajv
    New Member
    • Jun 2007
    • 152

    Linker error for constructor and destructor of CList

    Hi,
    While implementing CList class, I got linker errors for constructor and destructor. Below is the code -

    Code:
    template<class TYPE, class ARG_TYPE = const TYPE&>
    class CList
    {
    protected:
    	struct CNode
    	{
    		CNode* pNext;
    		CNode* pPrev;
    		TYPE data;
    	};
    public:
    	POSITION AddHead(ARG_TYPE newElement);
    	POSITION AddTail(ARG_TYPE newElement);
    	POSITION GetHeadPosition() const;
                    void RemoveAll();
                   CNode* NewNode(CNode*, CNode*);
    	~CList();
    	
                    CNode* m_pNodeHead;
    	CNode* m_pNodeTail;
    	int	m_nCount;
    	CNode* m_pNodeFree;
    	struct CPlex* m_pBlocks;
    	int m_nBlockSize;
    
    	CNode* NewNode(CNode*, CNode*);
    	void FreeNode(CNode*);
    );
    //For CPP file
    Code:
    template<class TYPE, class ARG_TYPE>
    CNode* CList<TYPE, ARG_TYPE>::NewNode(CNode* pPrev, CNode* pNext)
    {
    	if (m_pNodeFree == NULL)
    	{
    		// add another block
    		CPlex* pNewBlock = CPlex::Create(m_pBlocks, m_nBlockSize,
    				 sizeof(CNode));
    
    		// chain them into free list
    		CNode* pNode = (CNode*) pNewBlock->data();
    		// free in reverse order to make it easier to debug
    		pNode += m_nBlockSize - 1;
    		for (INT_PTR i = m_nBlockSize-1; i >= 0; i--, pNode--)
    		{
    			pNode->pNext = m_pNodeFree;
    			m_pNodeFree = pNode;
    		}
    	}
    
    
    	CList::CNode* pNode = m_pNodeFree;
    	m_pNodeFree = m_pNodeFree->pNext;
    	pNode->pPrev = pPrev;
    	pNode->pNext = pNext;
    	m_nCount++;
    	::new( (void*)( &pNode->data ) ) TYPE;
    	return pNode;
    }
    
    inline POSITION CList<TYPE, ARG_TYPE>::GetHeadPosition() const
    	{ return (POSITION) m_pNodeHead; }
    
    template<class TYPE, class ARG_TYPE>
    CList<TYPE, ARG_TYPE>::CList(int nBlockSize)
    {
    	
    
    	m_nCount = 0;
    	m_pNodeHead = m_pNodeTail = m_pNodeFree = NULL;
    	m_pBlocks = NULL;
    	m_nBlockSize = nBlockSize;
    }
    template<class TYPE, class ARG_TYPE>
    POSITION CList<TYPE, ARG_TYPE>::AddTail(ARG_TYPE newElement)
    {
    	CNode* pNewNode = NewNode(m_pNodeTail, NULL);
    	pNewNode->data = newElement;
    	if (m_pNodeTail != NULL)
    		m_pNodeTail->pNext = pNewNode;
    	else
    		m_pNodeHead = pNewNode;
    	m_pNodeTail = pNewNode;
    	return (POSITION) pNewNode;
    }
    template<class TYPE, class ARG_TYPE>
    void CList<TYPE, ARG_TYPE>::RemoveAll()
    {
    	// destroy elements
    	CNode* pNode;
    	for (pNode = m_pNodeHead; pNode != NULL; pNode = pNode->pNext)
    		pNode->data.~TYPE();
    
    	m_nCount = 0;
    	m_pNodeHead = m_pNodeTail = m_pNodeFree = NULL;
    	m_pBlocks->FreeDataChain();
    	m_pBlocks = NULL;
    }
    template<class TYPE, class ARG_TYPE>
    CList<TYPE, ARG_TYPE>::~CList()
    {
    	RemoveAll();
    	m_nCount = 0;
    }
    I am getting the following linker errors -
    error LNK2019: unresolved external symbol "public: __thiscall CList<int,int>: :~CList<int,int >(void)" (??1?$CList@HH@ @QAE@XZ) referenced in function _main

    error LNK2019: unresolved external symbol "public: __thiscall CList<int,int>: :CList<int,int> (int)" (??0?$CList@HH@ @QAE@H@Z) referenced in function _main

    No idea why this is happening. The constructor and destructor, both are public.

    In main, I am using it like this-
    Code:
    class CPerson
    {
    public:
    	int age;
    	CString sFullName;
    	CPerson () {int age=10;}
    	~CPerson();
    };
    
    int main()
    {
    CList<CPerson, CPerson*> m_listPerson;
    
    Person* lpPerson = new CPerson;
    lpPerson->sFullName = "Rocky Billbao";
    m_listPerson.AddTail(lpPerson);
    
    lpPerson = new CPerson;
    lpPerson->sFullName        = "Elvis Presley";
     m_listPerson.AddTail(lpPerson);
    
    return 0;
    }
    Last edited by Banfa; Nov 19 '09, 09:34 AM. Reason: Added [Code] ... [/code] tags
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    Hmmm I can't see a constructor in you CList class which with all those pointer members has to be a bad idea.

    That aside you appear to have defined you template in a header(h) and a source(cpp) file. Are you trying to compile the cpp file separately?

    That doesn't work with templates, a template is not a class, it is a pattern for the compiler to use to create a class (if needed). As such when you use a template the compiler needs to have visibility of the entire code for the template. That is the declaration of the class and the definitions of all its methods.

    You should put your template all into a single file, or if you must use 2 files then do not call the source file .cpp (I have used hpp in the past) use something else and #include it into the header after the class definition.

    Comment

    Working...