==运算符重载 (operator overload) 时几个报错的解决方法
第一次学习用C++ 的运算符重载,记录一下报错的解决方法以及改进过程。针对vector容器,有一个判断给定元素是否在vector中的函数:std::find(vec.cbegin(), vec.cend(), element);但这个函数只能用在vector元素为内置类型的时候,如果vector 元素类型为类或者结构体,则需要在类或者结构体中重载 == 运算符。version1:报错 ...
第一次学习用C++ 的运算符重载,记录一下报错的解决方法以及改进过程。
针对vector容器,有一个判断给定元素是否在vector中的函数:std::find(vec.cbegin(), vec.cend(), element);
但这个函数只能用在vector元素为内置类型的时候,如果vector 元素类型为类或者结构体,则需要在类或者结构体中重载 == 运算符。
version1:报错 bool must take exactly one argument == operator implementation file [duplicate]
// struct //
struct NeighborPointIdxPair
{
int index1;
int index2;
bool operator==(const NeighborPointIdxPair & pair1, const NeighborPointIdxPair & pair2)
{
return (pair1.index1 == pair2.index1 &&
pair1.index2 == pair2.index2)||
(pair1.index1 == pair2.index2 &&
pair1.index2 == pair2.index1);
}
};
在stackoverflow 上找到了答案:https://stackoverflow.com/questions/32685139/bool-must-take-exactly-one-argument-operator-implementation-file
You are comparing the implicit this
object to the other object
改为version2,如下。
注:在《C++Primer》 上也看到过重载 operator== 不用this,用两个形参的 (p497),就像version1 一样,为什么我的就报错呢,还不明白具体原因,再研究==
version2:报错:error: passing xxx as 'this' argument of xxx discards qualifiers
// struct //
struct NeighborPointIdxPair
{
int index1;
int index2;
bool operator==(const NeighborPointIdxPair & pair)
{
return (pair.index1 == this->index1 &&
pair.index2 == this->index2)||
(pair.index1 == this->index2 &&
pair.index2 == this->index1);
}
};
原因是,成员函数通过一个名为this 的额外的隐式参数来访问调用它的哪个对象。当我们调用一个成员函数(如operator==)时,用请求该函数的对象地址初始化this。this 默认情况下是一个指向非常量对象的常量指针,即this指针存储的地址不能变,但它指向的对象的内容可以变。那也就是说,不能在一个常量对象上调用普通的成员函数。
但我在后面的函数中使用上面定义的结构体类型的对象时,我定义成了常量引用,因为我在函数中不会改变这个对象的值,这就是报错的原因!如下所示:
/*
****************************************************************
********** Check the existence in vector of a element **********
****************************************************************
*/
// true: element exists in vector; false: not in vector
bool inVector(
const NeighborPointIdxPair & PIdxPair,
const std::vector<NeighborPointIdxPair> & PIdxPairVec
)
{
// if (PIdxPairVec.empty())
// {
// std::cout << "inVector(): The input vector is empty!" << std::endl;
// return (false);
// }
auto it = std::find(PIdxPairVec.cbegin(), PIdxPairVec.cend(), PIdxPair);
return (!(it == PIdxPairVec.cend()));
}
解决方法就是应该把this 设置为指向常量的指针,有助于提高函数的灵活性。然而this是隐式的,不出现在参数列表中,所以C++的规定就是在成员函数的形参列表后面加上const关键字。
也就是将运算符重载函数声明为:常量成员函数(const member function)
因为在常量成员函数中,this 是指向常量的指针,所以常量成员函数不能改变调用它的对象的内容。
常量对象,常量对象的引用和指针都只能调用常量成员函数。
将不会改变对象内容的成员函数设置为常量成员函数,有助于提高类/结构体使用的灵活性
详见 《C++Primer 第5版》p231
由此得到version3, 如下
version3:
// struct //
struct NeighborPointIdxPair
{
int index1;
int index2;
bool operator==(const NeighborPointIdxPair & pair) const
{
return (pair.index1 == this->index1 &&
pair.index2 == this->index2)||
(pair.index1 == this->index2 &&
pair.index2 == this->index1);
}
};
但是这个还不够好,因为一个类或者结构体的某个操作是检查相等性,则应定义operator==; 有了operator==, 通常也需要 operator!=
------《C++Primer 第5版》p492
于是有了version 4
version 4:
// struct //
struct NeighborPointIdxPair
{
int index1;
int index2;
bool operator==(const NeighborPointIdxPair & pair) const
{
return (pair.index1 == this->index1 &&
pair.index2 == this->index2)||
(pair.index1 == this->index2 &&
pair.index2 == this->index1);
}
bool operator!=(const NeighborPointIdxPair & pair) const
{
return (pair.index1 != this->index1 ||
pair.index2 != this->index2)&&
(pair.index1 != this->index2 ||
pair.index2 != this->index1);
}
};
相等运算符和不相等运算符中的一个应该把工作委托给另一个,这意味着其中一个运算符应该负责实际比较对象的工作,而另一个运算符只是调用哪个真正工作的运算符。 ------《C++Primer 第5版》p498
于是有了version 5
version 5:
// struct //
struct NeighborPointIdxPair
{
int index1;
int index2;
bool operator==(const NeighborPointIdxPair & pair) const
{
return (pair.index1 == this->index1 &&
pair.index2 == this->index2)||
(pair.index1 == this->index2 &&
pair.index2 == this->index1);
}
bool operator!=(const NeighborPointIdxPair & pair) const
{
return !(this->operator==(pair));
}
};
这样好多了~
更多推荐
所有评论(0)