代码之家  ›  专栏  ›  技术社区  ›  rilent

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

  •  -1
  • rilent  · 技术社区  · 10 年前

    所以基本上我尝试使用赋值运算符来分配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而是空的,我不明白为什么,因为在我的运算符“monGrape”中填充了。所以,当我第一次尝试使用这个运算符时,似乎在返回值时做了一些错误。

    根据:

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

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

    2 回复  |  直到 10 年前
        1
  •  2
  •   florian    10 年前

    赋值运算符应该为“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;
    }
    

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

        2
  •  1
  •   Community CDub    8 年前

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

    由于您已经对复制构造函数进行了编码,因此应该使用复制/交换习惯用法编写赋值运算符: 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 已添加到仅交换 全部的 左侧参数和右侧参数之间的成员。我强调 全部的 如果你没有发布所有的班级成员。

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

    编辑:制造 交换 一个朋友功能,正如T.C.的评论所建议的那样。