i'm doing program for people register.
I have class CRegister:
int personCount
int personSize
Person ** persons
Struct Person
char * name
char * surname
Places ** oldPlaces // here is former residence of this person
and struct oldPlaces
char date[11]
char * street
char * city
In every class/struct i have constructor which allocated empty memory for instance and metods add which added people or place.
The problem is how can implement copy constructor?
I have this for CRegister
CRegister::CRegister(const CRegister& b):personCount(b.personCount), personSize(b.personSize){
persons = new Person*[b.personSize];
personCount = 0;
personSize = b.personSize;
for (int i = 0; i < personSize; i++){
persons[i] = new Person();
persons[i].addPerson(b.persons[i]->id, b.persons[i]->name, b.persons[i]->surname);
}
But i want to copy oldPlaces also...
Thanks for any advice.
You should create a copy constructor for Person
as well and use it for each person in the array.
for (int i = 0; i < personSize; i++)
persons[i] = new Person(*b.persons[i]);
And copy the places in it:
Person::Person(const Person &b) {
...
// (Note that you will have to do a deep copy for the strings here as well)
oldPlaces = new Places *[oldPlacesCount];
for (int i = 0; i < oldPlacesCount; i++)
oldPlaces[i] = new Places(*b.oldPlaces[i]);
}
And then maybe also create a copy constructor for Places
etc.
EDIT: Yes, and you need to add oldPlacesCount
.
First, the problem more or less solves itself if you use std::string
and std::vector
. If you insist on using pointers, you'll have to do a deep copy yourself (along with assignment and destructors). In each object, you'll have to visit all of the pointers, "cloning" the sub-objects. And you'll have to handle the case where the allocations fail, which could leave objects of type Person
and Places
in an inconsistent state. Getting this right requires a lot of code, and a high degree of C++ expertise. You don't want to go that route. (Writing a C++ class which has two raw pointers to dynamically allocated memory can be very complicated. Using shared_ptr
or scoped_ptr
makes it a lot simpler, but still not as simple as using vector
and string
.)
Just to make it clear what is involved, here's what's needed for Place
, if you don't use the standard library:
struct Place
{
char date[11];
char* street;
char* city;
Place()
: street( NULL )
, city( NULL )
{
memset( date, '\0', sizeof( date ) );
}
Place( Place const& other )
: street( NULL )
, city( NULL )
{
memcpy( date, other.date, sizeof( date ) )
try {
street = new char[ strlen( other.street ) + 1 ];
strcpy( street, other.street );
city = new char[ strlen( other.city ) + 1 ];
strcpy( city, other.city );
} catch ( ... ) {
delete [] street;
delete [] city;
throw;
}
}
Place& operator=( Place const& other )
{
Place tmp( other );
memcpy( date, other.date, sizeof( date ) );
std::swap( street, other.street );
std::swap( city, other.city );
return *this;
}
~Place()
{
delete [] street;
delete [] city;
}
};
Person
is even more complicated, because you have to initialize the entire array oldPlaces
to NULL
, then to the copies in a try block, and delete them if anything goes wrong.
In practice, the first thing anyone with any experience in C++ would do, if for some reason he or she couldn't use the standard library, would be to implement a (probably simplified) version of std::string
and std::vector
, and use them. Try blocks like in the copy constructor above are typically an indication that the programmer doesn't really understand C++. All allocations and frees in code like the above would be wrapped in a smaller, more primitive classes, each of which managed at most one dynamically allocated resource. Thus, even in keeping very close to what you have written, one would probably develop a StringPtr
class, and use that in Person, etc. Similarly, one would use an array of Person
and an array of Place
, rather than arrays of pointers.
I don't know to what degree your structures have been imposed by your teacher, but this is not the way one programs in C++.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.