2015-02-25 3 views
0

поэтому в основном им пытаются использовать оператор присваивания в пути выделить 2 ВАР:назначение и конструктор копирования в C++

S solutionCourante, bestSolution; //(S is a template class) 
bestSolution = solutionCourante = solutionInitiale; 

Вот оператор я имею дело с:

template <class S, class T> 
const Graphe<S,T> & Graphe<S,T>::operator = (const Graphe<S,T> & graphe) 
{ 

this->lSommets = graphe.lSommets->copieListe(graphe.lSommets); 
this->lAretes = graphe.lAretes->copieListe(graphe.lAretes); 

return *this; 
} 

Вот мой конструктор копирования:

template <class S, class T> 
Graphe<S,T>::Graphe(const Graphe<S,T> & graphe) 
{ 
*this = graphe; 
} 

(я знаю, что конструктор копирования немного плохо закодированы, но УНР ks)

Так что в любое время я вижу, что «bestSolution» и «solutionCourante» не являются NULL, но пустыми, и я не понимаю, почему, поскольку в моем операторе «monGraphe» заполняется. Поэтому мне кажется, что я делаю что-то неправильно, когда возвращаю значение, первый раз, когда я пытаюсь сделать этого оператора.

По:

const Graphe<S,T> & Graphe<S,T>::operator = (const Graphe<S,T> & graphe) 

Graphe это элемент я хочу, чтобы скопировать и мы получили * это = Graphe?

+0

С каких пор '=' оператор распределения? –

+0

Привет, английский не мой родной язык извините, может быть, «аффектация» лучше? – rilent

+0

@rilent, который называется оператором присваивания. Измените свой заголовок, чтобы он был более точным. –

ответ

2

Оператор присваивания должен назначать значение «this», а не выделять новое.

template <class S, class T> 
Graphe<S,T> & Graphe<S,T>::operator = (const Graphe<S,T> & graphe) 
{ 
    lSommets = graphe.lSommets ? new PElement<Sommet<T>>(*graphe.lSommets) : nullptr; 
    lAretes = graphe.lAretes ? new PElement<Arete<S,T>>(*graphe.lAretes) : nullptr; 
    prochaineClef = graphe.prochaineClef; 
    return *this; 
} 
template <class S, class T> 
Graphe<S,T>::Graphe(const Graphe<S,T> & graphe) 
{ 
    *this = graphe; 
} 

Вообще говоря, вы не должны вернуть то, что выделяется в куче с новым, потому что любая информация о владельце теряется. Вероятно, вы должны попытаться использовать интеллектуальные указатели, такие как std :: unique_ptr.

+1

У вас есть memleak с 'operator =', поскольку вы не удаляете предыдущий указатель. После исправления ваш конструктор, вероятно, вызовет UB, поскольку 'lSommets' и' lAretes' не инициализируются. – Jarod42

+0

Я установил его с помощью кодирования 1 метод -> copylist() – rilent

+0

Этот ответ очень верен, как обычно делается. Конструктор копирования должен выполнять основную часть работы, тогда как оператор присваивания использует команду copy/swap, используя конструктор копирования в качестве «помощника». – PaulMcKenzie

1

Ответ уже был отправлен, но использует метод, когда оператор присваивания выполняет большую часть работы.

Поскольку вы уже закодированы конструктор копирования, ваш оператор присваивания должен быть записан с помощью копирования/своп идиома: What is the copy-and-swap idiom?

Что обычно делается (если вы хотите синергию между оператором присваивания и конструктор копирования) будет иметь копию конструктор выполняет основную часть работы, тогда как оператор присваивания использует конструктор копирования (и деструктор).

Вот ваш код с помощью копирования/свопа:

#include <algorithm> 
//... 
template <class S, class T> 
class Graphe 
{ 
    //... 
    friend void swap(Graphe<S,T>& lhs, Graphe<S,T>& rhs) 
    { 
     std::swap(lhs.lAretes, rhs.lAretes); 
     std::swap(lhs.lSommets, rhs.lSommets); 
     std::swap(lhs.prochaineClef, rhs.prochaineClef); 
    } 
    //... 
}; 
//... 
template <class S, class T> 
Graphe<S,T>::Graphe(const Graphe<S,T> & graphe) : 
{ 
    lSommets = graphe.lSommets ? new PElement<Sommet<T>>(*graphe.lSommets) : nullptr; 
    lAretes = graphe.lAretes ? new PElement<Arete<S,T>>(*graphe.lAretes) : nullptr; 
    prochaineClef = graphe.prochaineClef; 
} 

template <class S, class T> 
Graphe<S,T>& Graphe<S,T>::operator = (Graphe<S,T> graphe) 
{ 
    swap(*this, graphe); 
    return *this; 
} 

Функция называется swap был добавлен в шаблон класса, который просто SWAPS все членов между левой и правой руки параметра. Я подчеркиваю все в том случае, если вы не опубликовали всех своих участников.

Предполагая, что ваш конструктор копий является ошибкой, а ваш деструктор работает и без ошибок, приведенный выше код будет работать правильно.

Редактировать: Сделано swap Функция друга, как предложено комментариями T.C.

+0

Я действительно не знал об этом, спасибо за дополнительную информацию, я протестировал его, и он работает хорошо. Таким образом, это больше похоже на выбор кодировки, но использование метода copy/swap является истинным. – rilent

+0

Это больше, чем «выбор». Написание оператора присваивания таким образом гарантирует, что он будет работать, при условии, что у вас есть рабочий конструктор и деструктор. Ссылка, которую я опубликовал в ответ, показывает, почему. – PaulMcKenzie

+0

'swap' должен, вероятно, быть другом, а не членом (или если член должен поменять аргумент и' * this'). –

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