c ++中的赋值运算符模板和复制构造函数

时间:2015-02-25 15:39:21

标签: c++ assignment-operator

所以基本上我试图使用赋值运算符来分配2个变量:

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;
}

(我知道构造函数副本编码有点不好但有效)

所以在任何时候,我都可以看到“bestSolution”和“solutionCourante”不是NULL而是空的,我不明白为什么因为在我的运算符“monGraphe”中被填充。所以看起来我在返回值时做错了,第一次尝试做这个操作符。

根据:

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

graphe是我要复制的项目,我们得到了* this = graphe?

2 个答案:

答案 0 :(得分:2)

赋值运算符应该为&#34;这个&#34;分配一个值,而不是分配一个值。

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;
}

一般来说,您不应该使用new返回堆上分配的内容,因为任何所有权信息都会丢失。您应该尝试使用智能指针,例如std :: unique_ptr。

答案 1 :(得分:1)

已经发布了答案,但使用了让赋值运算符完成大部分工作的方法。

由于您已经编写了复制构造函数,因此应使用复制/交换习惯用法编写赋值运算符:What is the copy-and-swap idiom?

通常所做的事情(如果你想要赋值运算符和复制构造函数之间的协同作用)是让复制构造函数完成大部分工作,而赋值运算符则使用复制构造函数(和析构函数)。

以下是使用copy / swap的代码:

#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的函数被添加到模板类中,该函数只交换左手和右手参数之间成员的所有。如果您没有发布所有班级成员,我会强调所有

假设您的复制构造函数没有错误,并且您的析构函数正在运行且没有错误,则上面的代码将正常工作。

编辑:根据T.C。

的评论建议,使swap成为朋友功能