Я пытаюсь написать конструктор копирования для моего вектора указателей на объект, инициализированный и объявленный в классе Shop. Рассматриваемый вектор:
std::vector <gCustomer*> vCustomer;
Он также был объявлен в конструкторе gShop и удален через цикл в деструкторе.
Теперь я хочу иметь глубокую копию вектора указателей в конструкторе копирования. Но на самом деле ничего не копируется, проверка его размера остается равной нулю или сбой программы, если мне удастся запустить программу и получить доступ к vCustomer. (Обратите внимание, что если я оставлю конструктор копирования, чтобы использовать конструктор копии по умолчанию, программа работает нормально)
gShop::gShop(const gShop & cShop)
{
for(int i = 0; i < (int)vCustomer.size(); ++i)
{
vCustomer[i] = cShop.vCustomer[i];
}
}
благодаря
Примечание. У меня также есть назначенный оператор
gShop gShop::operator=(const gShop & rhs)
{
if (this == &rhs) return *this;
for(int i = 0; i < (int)vCustomer.size(); ++i)
{
delete vcustomer[i];
vCustomer[i] = new gCustomer;
vCustomer[i]= rhs.vCustomer[i];
}
}
Вы внедрили свой конструктор копирования и оператор присваивания неправильно, они делают мелкие копии, а не глубокие копии, и они не изменяют размер целевого вектора. Здесь создатель глубокой копии копии
gShop::gShop(const gShop & cShop)
{
for(int i = 0; i < (int)cShop.vCustomer.size(); ++i)
{
if (cShop.vCustomer[i])
vCustomer.push_back(new gCustomer(*cShop.vCustomer[i]));
else
vCustomer.push_back(NULL);
}
}
и здесь оператор копирования глубоких копий
gShop& gShop::operator=(const gShop & rhs)
{
if (this == &rhs) return *this;
// clear any existing data
for(int i = 0; i < (int)vCustomer.size(); ++i)
delete vcustomer[i];
vcustomer.clear();
// add the new data
for(int i = 0; i < (int)rhs.vCustomer.size(); ++i)
{
if (rhs.vCustomer[i])
vCustomer.push_back(new gCustomer(*rhs.vCustomer[i]));
else
vCustomer.push_back(NULL);
}
return *this;
}
В основном проблема заключалась в том, что вы копировали указатели вместо выделения новой памяти. Если вам нужна глубокая копия, вам необходимо выделить новую память.
Конечно, есть большой вопрос, почему вы используете вектор указателей. Одним из больших преимуществ вектора является то, что вам больше не нужно явно управлять памятью, используя вектор указателей, которые вы потеряли. Я не знаю, что вы программируете, но мне кажется, что std::vector<gCustomer>
будет лучше, чем std::vector<gCustomer*>
. В std::vector<gCustomer>
вам не нужно писать конструктор или оператор присваивания, глубокая копия будет выполняться автоматически (при условии, что gCustomer
выполняет глубокую копию).
Петля
gShop::gShop(const gShop & cShop)
{
for(int i = 0; i < (int)vCustomer.size(); ++i)
{
vCustomer[i] = cShop.vCustomer[i];
}
}
использует неправильный предел. Он должен начинаться от 0 до длины существующего объекта:
i < (int)cShop.vCustomer.size()
std :: vector <> имеет сам конструктор копирования, чтобы сделать глубокую копию. Таким образом, создатель копирования, предоставленный компилятором, будет выполнять ту работу, которую вы хотите на самом деле. Если вы хотите реализовать его самостоятельно, это лучше в списке инициализации конструктора gShop.
gShop::gShop(const gShop & cShop):vCustomer(cShop.vCustomer)
{
}
Размер vCustomer всегда равен нулю в вашей копии ctor.
Я смущен вашим оператором =(). Что ты хочешь? Я предлагаю вам прочитать некоторые учебники, похожие на c++ праймер.