Thread: calling copy constructor from template

  1. #1
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267

    calling copy constructor from template

    I'm writing my own version of <vector> because my compiler eVC++ 3.0 does not support any STL templates, or exception handling. The problem I'm having is I can't get it to call the class's copy constructor when reallocating the array. It does the normal stuff, allocate temp variable then copy original array into new temp array.
    Code:
    typedef unsigned long size_type;
    ...
    ...
    T* pTemp = new T[nNewSize];
    for(size_type i = 0; i < nOldSize; i++)
    	pTemp[i] = m_array[i]; 
    delete[] m_array;
    m_array = pTemp;
    
    ...
    ...
    // vector's data items
    	T*	m_array;
    	size_type	m_nItems;
    	size_type	m_nCapacity;
    	size_type	m_nBlockSize;
    The blue colored line is where I expect the class's copy constructor to be called.

    The text class is pretty simple. I put a breakpoint inside the copy constructor but the program never breaks there.
    Code:
    class CMyClass
    {
    public:
    	CMyClass();
    	~CMyClass() {}
    	CMyClass(const CMyClass& c);
    
    protected:
    	int m_x;
    	int m_y;
    };
    
    CMyClass::CMyClass()
    {
    	m_x = 0;
    	m_y = 0;
    }
    
    CMyClass::CMyClass(const CMyClass& c)
    // This is the copy constructor (I hope) 
    {
    	m_x = c.m_x;
    	m_y = c.m_y;
    }
    I'm using VC++ 6.0 on XP to develop the template because it's easier than eVC++ 3.0.

    Here is the whole thing if anyone is interested. It hasn't been fully tested so there may be other errors. Also haven't done anything about an iterator -- yet.
    Code:
    #ifndef VECTOR_H__E038A84A_C63C_4EDD_B79B_86E9DF752DBE__INCLUDED_
    #define VECTOR_H__E038A84A_C63C_4EDD_B79B_86E9DF752DBE__INCLUDED_
    
    
    typedef unsigned long size_type;
    namespace mystd
    {
    	const int InitialBlockSize = 10;
    	template<class T>
    	T min(T n1, T n2)
    	{
    		return (n1 < n2) ? n1 : n2;
    	}
    	template<class T>
    	class vector
    	{
    	public:
    		vector() 
    		{
    			m_array = 0; 
    			m_nItems = 0;
    			m_nCapacity = 0;
    			m_nBlockSize = InitialBlockSize;
    		}
    		vector(size_type nItems) 
    		{
    			m_array = 0;
    			m_nItems = 0;
    			m_nCapacity = 0;
    			m_nBlockSize = InitialBlockSize;
    			Alloc(nItems);
    		}
    		vector(size_type n, const T& t)
    		{
    			m_array = 0;
    			m_nItems = 0;
    			m_nBlockSize = InitialBlockSize;
    			m_nCapacity = 0;
    			Alloc(n);
    			for(size_type i = 0; i < n; i++)
    				array[i] = t;
    		}
    		vector(const vector& v) 
    			// copy constructor
    		{
    			m_array = 0;
    			m_nItems = 0;
    			m_nCapacity = 0;
    			m_nBlockSize = InitialBlockSize;
    			Alloc(v.m_nItems);
    			for(size_type i = 0; i < n; i++)
    				array[i] = v.m_array[i];
    
    		}
    		T& front() {return m_array[0];}
    		T& back() {return m_array[m_nItems-1];}
    		size_type begin() {return 0;}
    		size_type end() {return m_mItems;}
    		void erase(size_type beg = -1, size_type end = -1)
    		{
    			if(beg == -1) beg = 0;
    			if(end == -1) end = m_nItems;
    			if(beg == 0 && end == m_nItems)
    			{
    			}
    		}
    		~vector()
    		{
    			if(m_array != 0)
    				delete[] m_array;
    		}
    		void resize(size_type nItems)
    		{
    			if(m_array == 0)
    			{
    				m_array = new T[nItems];
    				m_nItems = nItems;
    				m_nCapacity = nItems;
    			}
    			else
    			{
    				m_nCapacity = nItems;
    				T* pTemp = new T[nItems];
    				size_type n = min(m_nItems,nItems);
    				for(size_type i = 0; i < n; i++)
    					pTemp[i] = m_array[i];
    				delete[] m_array;
    				m_array = pTemp;
    
    			}
    			m_nItems = nItems;
    		}
    		void push_back(const T& obj)
    		{
    			Alloc(m_nItems + 1);
    			m_array[m_nItems++] = obj;
    		}
    		T& operator[](size_type index)
    		{
    			return m_array[index];
    		}
    		T& at(size_type index)
    		{
    			return m_array[index];
    		}
    		size_type size() const {return m_nItems;}
    		size_type capacity() const {return m_nCapacity;}
    
    	private:
    		void Alloc(size_type nItems)
    		{
    			// do nothing if there is room for
    			// nItems number of elements in the array
    			if(nItems < m_nCapacity)
    				return;
    			// current number of items + number of new
    			// items exceeds current capacity.  So we need to
    			// enlarge the array
    			size_type nNewCapacity = m_nCapacity;
    			while( nItems > nNewCapacity)
    			{
    				nNewCapacity += m_nBlockSize;
    			}
    			if(nNewCapacity == nItems)
    				nNewCapacity += m_nBlockSize;
    			T* pTemp = new T[nNewCapacity];
    			if(m_nItems > 0)
    			{
    				for(size_type i = 0; i < m_nItems; i++)
    					pTemp[i] = m_array[i];
    				delete[] m_array;
    			}
    			m_array = pTemp;
    			m_nCapacity = nNewCapacity;
    		}
    		T*	m_array;
    		size_type	m_nItems;
    		size_type	m_nCapacity;
    		size_type	m_nBlockSize;
    	};
    }; // namespace std;
    
    
    
    #endif // VECTOR_H__E038A84A_C63C_4EDD_B79B_86E9DF752DBE__INCLUDED_
    Last edited by Ancient Dragon; 09-28-2005 at 12:35 PM.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    What happens when you put the breakpoint on the blue line and step into the code? What functions does it call (if any)? Does the value of pTemp[i] get changed correctly?

  3. #3
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    I solved the problem. My test class did not have an overloaded assignment operator.

  4. #4
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Sometimes that confuses people... when you declare an instance of a class and use '=' to initialize the class in that same statement the compiler converts it into a call to the copy constructor but when you declare an instance of a class and then on a different statement use '=' it is the assignment operator that gets called:

    Code:
    Type Var1
    Type Var2(Var1);   // This is the copy constructor
    Type Var3 = Var2;  // This is also the copy constructor...
                       // it gets converted to Type Var3(Var2) by the compiler
    
    Type Var4;
    Type Var5;
    Var4 = Var5;       // This is the assignment operator
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Double template specializations
    By Sang-drax in forum C++ Programming
    Replies: 13
    Last Post: 08-23-2006, 01:25 PM
  2. Replies: 6
    Last Post: 12-06-2005, 09:23 AM
  3. Class Template Trouble
    By pliang in forum C++ Programming
    Replies: 4
    Last Post: 04-21-2005, 04:15 AM
  4. instantiated from here: errors...
    By advocation in forum C++ Programming
    Replies: 5
    Last Post: 03-27-2005, 09:01 AM
  5. templates with pointers
    By Cipher in forum C++ Programming
    Replies: 3
    Last Post: 11-18-2002, 11:45 AM