Мой конструктор копирования не удается .. как скопировать указатель на объект

0

Я пытаюсь написать конструктор копирования для моего вектора указателей на объект, инициализированный и объявленный в классе 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];
        }
    }
Теги:
copy-constructor

3 ответа

1
Лучший ответ

Вы внедрили свой конструктор копирования и оператор присваивания неправильно, они делают мелкие копии, а не глубокие копии, и они не изменяют размер целевого вектора. Здесь создатель глубокой копии копии

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 выполняет глубокую копию).

  • 0
    Я использую вектор указателей из-за причин предварительного объявления. Я не могу инициализировать объект в этом классе, но я могу инициализировать указатель на этот объект.
  • 0
    Я скопировал это строка для линии. Я получаю ошибку сегментации и отладчик точно определяет, что он вылетает в vCustomer.push_back (новый gCustomer (* cShop.vCustomer [i])) ??
Показать ещё 16 комментариев
1

Петля

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()
  • 1
    Конечно, когда вы делаете это, вам также нужно убедиться, что в vCustomer достаточно элементов, чтобы можно было его проиндексировать. Предшествовать циклу с помощью: vCustomer.resize (cShop.vCustomer.size ());
-1

std :: vector <> имеет сам конструктор копирования, чтобы сделать глубокую копию. Таким образом, создатель копирования, предоставленный компилятором, будет выполнять ту работу, которую вы хотите на самом деле. Если вы хотите реализовать его самостоятельно, это лучше в списке инициализации конструктора gShop.

gShop::gShop(const gShop & cShop):vCustomer(cShop.vCustomer)
{
}

Размер vCustomer всегда равен нулю в вашей копии ctor.

Я смущен вашим оператором =(). Что ты хочешь? Я предлагаю вам прочитать некоторые учебники, похожие на c++ праймер.

  • 0
    Это упоминается в правиле трех: ( stackoverflow.com/questions/4172722/what-is-the-rule-of-three )
  • 0
    Этот ответ просто неверен. Конструктор векторного копирования делает поверхностное копирование, когда он работает с вектором указателей.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню