Copy Constructors

This is a discussion on Copy Constructors within the C++ Programming forums, part of the General Programming Boards category; Hi I have had a break from C++ for a while because of exams and I am trying to get ...

  1. #1
    Registered User
    Join Date
    Feb 2003
    Posts
    76

    Question Copy Constructors

    Hi I have had a break from C++ for a while because of exams and I am trying to get back into it. I have created a linked list and am trying to use the following statement.

    theRecord = new Record(tempRecord);

    were the record is a pointer and tempRecord is of class record. Now my question is, because i have overloaded the constructor must I overload the copy constructor as well because i keep getting a complile time error saying 'can't convert typer class record to char *'

    Many thanks

  2. #2
    Compulsive Liar Robc's Avatar
    Join Date
    Jul 2004
    Posts
    149
    >because i have overloaded the constructor must I overload the copy constructor as well
    Only if it makes sense to do so. If the default copy constructor (there is one if you don't write one!) doesn't do what you want, such as perform a deep copy of pointer members, you need to write a copy constructor that does. And when you do that, it's usually a good idea to write an assignment operator as well.

    >'can't convert typer class record to char *'
    Aroo? Can you post some code? Preferrably something small that exhibits the problem so that we can compile it and see for ourselves.

  3. #3
    Registered User
    Join Date
    Feb 2003
    Posts
    76
    Yeah sure because im confused now because I thought that would of been logical, to have to re-write that one too.
    Code:
    // Node header File Version 1
    // For Address Book Version 1 Build 3 Onwards
    
    // Include The Record Header File
    #include "Record.h"
    
    //Class definition
    class Node
    {
    public:
    	// Constructors
    	Node();
    	Node(Record *theRecord);
    
    	//Destructors
    	~Node();
    
    	// Accessors
    	Record * getItsRecord();
    	void setItsRecord(Record *theRecord);
    
    	Node * getItsNext();
    	void setItsNext(Node *theNext);
    
    	// Insert New Data into the list
    	void Insert(Record *theRecord);
    private:
    	// Pointer To Next Node in the list
    	Node *itsNext;
    	// Data that the Node holds
    	Record *itsRecord;
    };
    
    // Initalize all Data to 0
    Node::Node()
    {
    	itsRecord = 0;
    	itsNext = 0;
    }
    
    // Intialize data but still set next to 0;
    Node::Node(Record *theRecord)
    {
    	itsRecord = new Record(theRecord);
    	itsNext = 0;
    }
    Just tell me anything else you need many thanks. Its just so annoying that I used to be able to sort things like this out but after 6 months break it completely eludes me

  4. #4
    Compulsive Liar Robc's Avatar
    Join Date
    Jul 2004
    Posts
    149
    And the code for Record is...?
    Code:
    itsRecord = new Record(theRecord);
    This is suspect because a copy constructor should be declared as:
    Code:
    Class(const Class& c);
    And you pass a pointer.
    Last edited by Robc; 07-12-2004 at 02:21 PM.

  5. #5
    Registered User
    Join Date
    Feb 2003
    Posts
    76
    Code:
    // Record Header File Version 1
    // For Address Book Version 1 Build 2 Onwards
    
    class Record
    {
    public:
    	// Constructors
    	Record();
    	Record(char* theName);
    	Record(char* theName, char* theAddress);
    	Record(char* theName, char* theAddress, char* theNumber);
    	Record(char* theName, char* theAddress, char* theNumber, int theAge);
    
    	// Destructor
    	~Record();
    
    	// Accessors
    	char * getItsName();
    	char * getItsAddress();
    	char * getItsNumber();
    	int	   getItsAge();
    
    	void setItsName(char* theName);
    	void setItsAddress(char* theAddress);
    	void setItsNumber(char* theNumber);
    	void setItsAge(int theAge);
    
    private:
    	// Information that is collected form the user
    	char * itsName;
    	char * itsAddress;
    	char * itsNumber;
    	int itsAge;
    };
    
    //Constructors Initalize values with 0
    Record::Record()
    {
    	itsName = 0;
    	itsAddress = 0;
    	itsNumber = 0;
    	itsAge = 0;
    }
    
    Record::Record(char *theName)
    {
    	itsName = theName;
    	itsAddress = 0;
    	itsNumber = 0;
    	itsAge = 0;
    }
    
    Record::Record(char *theName, char *theAddress)
    {
    	itsName = theName;
    	itsAddress = theAddress;
    	itsNumber = 0;
    	itsAge = 0;
    }
    
    Record::Record(char *theName, char *theAddress, char *theNumber)
    {
    	itsName = theName;
    	itsAddress = theAddress;
    	itsNumber = theNumber;
    	itsAge = 0;
    }
    
    Record::Record(char *theName, char *theAddress, char *theNumber, int theAge)
    {
    	itsName = theName;
    	itsAddress = theAddress;
    	itsNumber = theNumber;
    	itsAge = theAge;
    }
    
    //Destructor deletes and nullifys everything
    Record::~Record()
    {
    	itsName = 0;
    	itsAddress = 0;
    	itsNumber = 0;
    	itsAge = 0;
    }
    
    // Accessors
    char * Record::getItsAddress()
    {
    	return itsAddress;
    }
    
    char * Record::getItsName()
    {
    	return itsName;
    }
    
    char * Record::getItsNumber()
    {
    	return itsNumber;
    }
    
    int Record::getItsAge()
    {
    	return itsAge;
    }
    
    void Record::setItsAddress(char * theAddress)
    {
    	itsAddress = theAddress;
    }
    
    void Record::setItsName(char *theName)
    {
    	itsName = theName;
    }
    
    void Record::setItsNumber(char *theNumber)
    {
    	itsNumber = theNumber;
    }
    
    void Record::setItsAge(int theAge)
    {
    	itsAge = theAge;
    }
    Sorry mate

  6. #6
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Your not calling the copy constructor. The copy constructor traditionally takes a const reference to the type of object, while theRecord is a pointer. Depending on how you want your memory to be managed, you either want to copy the object pointed to ('new Record(*theRecord)'), or simply assign the pointer (however, this means that your node is now responsible for that memory, and the rest of your code better be aware of that -- this is probably not the route to go).

  7. #7
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    The above of course assumes that you have defined your copy constructor... Which I now see has not been done.

    As an aside, you can simplify your other constructor with default arguments (that is, 1 ctor instead of 4).

    *edit*
    And when assigning c-strings (char*'s), use strcpy, and don't set the pointers equal. That can lead to trouble.

  8. #8
    Registered User
    Join Date
    Feb 2003
    Posts
    76
    Your starting to lose me a bit. So the compile time error will go if i define a copy constructor??

  9. #9
    Compulsive Liar Robc's Avatar
    Join Date
    Jul 2004
    Posts
    149
    >So the compile time error will go if i define a copy constructor??
    The compile-time error will go away if you pass a Record instead of a pointer to a Record. That means dereferencing the pointer:
    Code:
    itsRecord = new Record(*theRecord);
    But that still won't be the end of your problems because the default copy constructor won't copy your data. It'll just copy your pointers and then you'll have aliasing problems where multiple records point to the same data.

  10. #10
    Registered User
    Join Date
    Feb 2003
    Posts
    76
    Right forgive me for been completly thick today but my understanding was (This is probably completely wrong half a year does this to you)
    That a copy constructor takes a reference to an object as a parameter. I thought that passing a pointer through would mean it would use that pointer for an address for the reference to a particular object. Is this wrong??

  11. #11
    Compulsive Liar Robc's Avatar
    Join Date
    Jul 2004
    Posts
    149
    >Is this wrong??
    Yes. The reference created from the argument you pass is reference-to-T where T is the type of the argument. If you pass a Record then it's reference-to-Record. If you pass a pointer to a Record, it's reference-to-pointer-to-Record. That's a type mismatch because the copy constructor expects a reference-to-Record, and thus, an error.

  12. #12
    Registered User
    Join Date
    Feb 2003
    Posts
    76
    Are right I understand. Thanks a lot for your help. Your all stars at this board.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Copy constructors; Best practices (and private)
    By Mario F. in forum C++ Programming
    Replies: 15
    Last Post: 06-23-2006, 04:42 PM
  2. Help with copy constructors
    By nessie in forum C++ Programming
    Replies: 4
    Last Post: 04-24-2005, 07:50 AM
  3. 'Passing by Refrence for Efficiency', Copy Constructors?
    By Zeusbwr in forum C++ Programming
    Replies: 4
    Last Post: 10-23-2004, 07:11 AM
  4. Copy constructors and operator=()
    By filler_bunny in forum C++ Programming
    Replies: 13
    Last Post: 08-25-2003, 07:43 AM
  5. Copy constructors and private constructors
    By Eibro in forum C++ Programming
    Replies: 5
    Last Post: 11-24-2002, 09:16 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21