Какова правильная структура назначения копирования в C ++? - PullRequest
0 голосов
/ 12 февраля 2020

Я работаю со структурой данных бинарного дерева поиска и пришел к реализации семантики копирования. Поскольку я хочу сделать глубокую копию, я решил создать новый объект внутри назначения копирования и затем передать его за пределы функции. Однако, когда я вызываю назначение копирования, ничего не делается с переменной объекта, которую я хочу изменить. Что я делаю неправильно? Я предполагаю, что есть ошибка в определении ключевых слов в перегрузке оператора.

// copy assignment -- deep copy
bst operator=(const bst& bintree){
    std::cout<<"copy assignment invoked"<<std::endl;
    bst newbst{};//here I create a new object, so I am sure it is a deep copy
    newbst.insert(bintree.root->value);//I add the root first
    copy_part(bintree.root, newbst);//then I add the remaining nodes    
    return newbst;
}
void copy_part(Node<treepair>* x, bst& bintree){
        if(x->left!=nullptr){
            bintree.insert(x->left->value);     
                copy_part(x->left,bintree);
        }
        if(x->right!=nullptr){
            bintree.insert(x->right->value);        
                copy_part(x->right,bintree);
        }
}
...

int main(){

bt_INT bintree{};
/*
here i fill bintree
*/

bt_INT bintree_copy{};//made an empty tree

    bintree_copy = bintree;//copy assignment

   //however if i print bintree_copy it gives me an empty array.
   // what am I missing here?



}

Обратите внимание, что в определении оператора = я не написал bst &, потому что мне пришлось возвращать локальную переменную.

РЕДАКТИРОВАТЬ: я читаю ваши комментарии, и я сделал несколько изменений

class bst{
...

bst& operator=(const bst& bintree){

    (*this).clear();//I clear the nodes present in the LHS of the assignment    
    (*this).insert(bintree.root->value);//I insert the root first
    copy_part(bintree.root, *this);
    return *this;
}
void copy_part(Node<treepair>* x, bst& bintree){//I left this part since I need to perform a deep copy
        if(x->left!=nullptr){
            bintree.insert(x->left->value);     
                copy_part(x->left,bintree);
        }
        if(x->right!=nullptr){
            bintree.insert(x->right->value);        
                copy_part(x->right,bintree);
        }
}
 ...
};

Теперь все работает нормально. Теперь мне просто нужно справиться с конструктором копирования.

1 Ответ

0 голосов
/ 12 февраля 2020

Вам не нужно создавать временный объект в назначении копирования. Благодаря этому вы теряете изменения, внесенные локально в этот объект (временный bst-объект).

В основном самоназначение, выделение памяти и копирование элементов являются шагами, выполняемыми при копировании. Пример:

struct C
{
    std::unique_ptr<int[]> data;
    std::size_t size;
    // non-copy-and-swap assignment
    C& operator=(const C& other)
    {
        // check for self-assignment
        if(&other == this)
            return *this;
        // reuse storage when possible
        if(size != other.size)
        {
            data.reset(new int[other.size]);
            size = other.size;
        }
        std::copy(&other.data[0], &other.data[0] + size, &data[0]);
        return *this;
    }
    // note: copy-and-swap would always cause a reallocation
};

Пример ссылки на идеальный способ копирования: https://en.cppreference.com/w/cpp/language/copy_assignment

...