C++中的赋值运算符模板和复制构造函数
assignment operator template and copy constructor in c++
所以基本上我尝试使用赋值运算符来分配 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?
赋值运算符应该为 "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;
}
一般来说,你不应该 return 用 new 在堆上分配一些东西,因为任何所有权信息都会丢失。您可能应该尝试使用智能指针,例如 std::unique_ptr.
答案已经 posted,但使用了一种让赋值运算符完成大部分工作的方法。
因为你已经编写了复制构造函数,你的赋值运算符应该使用 copy/swap 惯用语来编写: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
的函数被添加到模板 class 中,它仅交换左右参数之间的 所有 成员。如果您没有 post 所有 class 成员,我强调 all。
假设您的复制构造函数没有错误,并且您的析构函数正在运行并且没有错误,上面的代码将正常工作。
编辑:根据 T.C.
的评论建议,将 swap
设为友元函数
所以基本上我尝试使用赋值运算符来分配 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?
赋值运算符应该为 "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;
}
一般来说,你不应该 return 用 new 在堆上分配一些东西,因为任何所有权信息都会丢失。您可能应该尝试使用智能指针,例如 std::unique_ptr.
答案已经 posted,但使用了一种让赋值运算符完成大部分工作的方法。
因为你已经编写了复制构造函数,你的赋值运算符应该使用 copy/swap 惯用语来编写: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
的函数被添加到模板 class 中,它仅交换左右参数之间的 所有 成员。如果您没有 post 所有 class 成员,我强调 all。
假设您的复制构造函数没有错误,并且您的析构函数正在运行并且没有错误,上面的代码将正常工作。
编辑:根据 T.C.
的评论建议,将swap
设为友元函数