2015-10-29 3 views
1

Я пытаюсь создать функцию глубокой копии для моей структуры. В основной программе я пытаюсь глубоко скопировать a в c, чтобы, наконец, напечатать строку «B». Что я делаю не так? Я знаю, что есть некоторые неясные вещи-указатели, которые мне сейчас не хватает.Структура глубокой копии C++

#include <iostream> 

using namespace std; 

struct Thing { 

     size_t length; 
     std::string txt; 
     struct Thing *things[]; 
}; 

struct Thing *deepCopy(struct Thing *origin) { 

     Thing tmp; 
     tmp.length = origin->length; 
     for(int i=0;i<tmp.length; ++i) 
      tmp.things[i] = deepCopy(origin->things[i]); 

     return &tmp; 
} 

int main() { 

     Thing a, b, *c; 

     a.length = 1; 
     a.things[0] = &b; 
     a.txt = "A"; 
     b.txt = "B"; 
     b.length = 0; 
     c = deepCopy(&a); 

     cout<<c->txt; 
     return 0; 
} 
+0

Включите все предупреждения, и проблема будет очевидна (это '-Wall' в gcc). Это поможет вам в будущем. – milleniumbug

+5

какая нечестивая смесь C++ и C! – SergeyA

+1

Помимо упомянутого уже локального аргумента, у вас также есть неопределенное поведение 'struct Thing * things [];' – SergeyA

ответ

1

Вы не можете вернуть адрес локальной переменной. В настоящий момент функция завершена, она больше не действительна. Передайте два указателя (источник и назначение) вместо функции

1

Вы возвращаете указатель на объект с автоматической продолжительностью хранения, так как объект находится в состоянии неопределенности после того, как элемент управления выходит из области видимости, разыменовывая ее с помощью c, - это неопределенное поведение. Либо верните полную копию объекта, а затем возьмите его адрес и поместите его в c или передайте ссылку или указатель на c в функцию (или сделайте deepCopy функцией-членом Thing и присвойте экземпляру вместо временного, который вероятно, лучшее решение).

5

Лучший способ выполнить глубокую копию - написать код, чтобы компилятор сделал это для вас. Компилятор автоматически создает конструктор копирования и оператор присваивания, который копирует каждый член объекта. Пока каждый член знает, как копировать себя, это обычно работает так, как вы хотите. Вероятно, он не будет работать автоматически, если у вас есть указатели и управляемая вручную память, поскольку указатели не знают, принадлежат ли они тому, на что они указывают. Если вы не используете указатели, вы, как правило, в порядке.

Так что, если вы пишете ваш объект, как это:

struct Thing 
{ 
    std::string txt; 
    std::vector<Thing> things; 
}; 

Копирование будет просто работать в автоматическом режиме.

Thing a; 
Thing b = a; // just works 

я удалил поле размера, потому что std::vector знает свой собственный размер, так что она не нужна.

+1

Наконец-то правильный ответ :) – SergeyA

+0

Дело в том, что мне нужна эта структура как есть :) Мне нужно реализовать функция глубокой копии. – Alessandro

+0

@ user5504743 Тот, кто дал вам эту структуру, не хорош в программировании. –

Смежные вопросы