关于重载运算符的思考

来源:互联网 发布:新浪微博淘宝客粉丝 编辑:程序博客网 时间:2024/04/30 05:43

在C++中重载运算符,能使运算符的功能得到扩展,如能够支持对类或结构体的操作.

       其实重载运算符也是一种特殊的函数调用方式,重载的方式有两种,一种是作为成员函数,一种是作为友元函数。其中[ ]只能作为成员函数进行重载,类属关系运算符“.” 、成员指针运算符“.*” 、作用域运算符“::” 、sizeof运算符和三目运算符“?:”是不能够重载的。当作为成员函数的时候,重载函数的参数个数比原来操作数个数要少一个,比如:‘+’运算符,原来是两个对象的加和,当作为成员函数的时候,参数只需要一个对象即可,因为成员函数可以直接调用当前对象的变量,所以只需要传递加和对象的参数即可。而当友元函数的时候,因为友元函数不能够调用当前对象的成员变量,所以传递的参数应该和原有的运算对象个数相同。

      在什么情况下需要重载运算符呢?比如我们在使用map结构时,我们想让map结构中能够存储我们定义的结构体或者是类对象,那么我们就需要重载运算符‘>’或者'<',map缺省是用less<Key>作为比较器,所以它要求作为Key的类要重载“<”操作符,没有重载“<”操作符,而是重载了“>”操作符就会报错。反之,也可以显式地用greater<Key>作为比较器,此时就必要重载Key类中的“>”操作符了。还有在vector结构中,如果我们想使用algorithm中的sort排序算法,则需要我们定义一个排序规则,也需要我们重载‘<’运算符,此处应该注意,当vector中放的是对象指针,不是对象的时候,一定要确保最后排序是按照真实的值进行排序而不是按照指针的大小进行排序的,例如:

class A
{
public:
  bool operator(const A* temp)
  {
     return this->a < temp->a;
  }
  A(int a)
  {
    this->a = a;
  }
  int a;
};
vector<A*> vec;
vec.push_back(new A(10));
vec.push_back(new A(5));
vec.push_back(new A(4));
sort(vec.begin(), vec.end);

然而排序的结果却不对
原来当我排序vector的时候,它比较的是指针,而不是对象,并且operator<重载符的参数应该用引用,而不是指针

解决办法:
1:声明一个全局的比较函数
例:
bool CompLess(const A* lhs, const A* rhs)
{
    return lhs->GetA() < rhs->GetA();
}
sort(vec.begin(), vec.end, CompLess);
2: 声明一个函数对象
class CompLess2
{
public:
    bool operator()(const A* lhs, const A* rhs)
    {
        return lhs->GetA() < rhs->GetA();
    }
};
sort(vec.begin(), vec.end, CompLess2); 

      最后说一下关于[ ]的重载情况,首先它有些不同,就是它只能以成员函数的形式给出,而且它的调用也很特殊,比如

class base{
public:
base();
base(int size);
~base();
base& operator [](int n);
void out()
{
cout<<x<<endl;
}
private:
base* next;
int x;
};base::base():x(10){}

base::base(int size){
next=new base[size];
}base& base::operator[](int n)
{
cout<<"调用重载函数!"<<endl;
if (n<0||n>5)
{
cout<<"越界"<<endl; exit(0);
}
return next[n];
}当我在主函数中:base obj[5];obj[5].out();这样是不会调用[]的重载函数的,而:base obj(5);obj[6].out();这样则会调用到[]重载函数,也就是[]是一个成员函数,第二种方法刚好是一个对象,然后调用其中的[]成员函数输出成员变量. 重载运算符还有好多的功能,如重载“=”实现类对象的深度赋值运算,赋予原来运算符所不具有的性质.

0 0
原创粉丝点击