c++ operator关键字
如何声明一个重载的操作符?
A: 操作符重载实现为类成员函数
重载的操作符在类体中被声明,声明方式如同普通成员函数一样,只不过他的名字包含关键字operator,以及紧跟其后的一个c++预定义的操作符。 可以用如下的方式来声明一个预定义的==操作符:
class person{ private: int age; public: person(int a){ this->age=a; } inline bool operator == (const person &ps) const; };
实现方式如下:
inline bool person::operator==(const person &ps) const { if (this->age==ps.age) return true; return false; }
调用方式如下:
#include using namespace std; int main() { person p1(10); person p2(20); if(p1==p2) cout<<”the age is equal!”< return 0; }
这里,因为operator ==是class person的一个成员函数,所以对象p1,p2都可以调用该函数,上面的if语句中,相当于p1调用函数==,把p2作为该函数的一个参数传递给该函数,从而实现了两个对象的比较。
B:操作符重载实现为非类成员函数(全局函数)
对于全局重载操作符,代表左操作数的参数必须被显式指定。例如:
#include #include using namespace std; class person { public: int age; public: }; bool operator==(person const &p1 ,person const & p2) //满足要求,左操作数的类型被显示指定 { if(p1.age==p2.age) return true; return false; } int main() { person rose; person jack; rose.age=18; jack.age=23; if(rose==jack) cout<<"ok"< return 0; }
C:如何决定把一个操作符重载为类成员函数还是全局名字空间的成员呢?
①如果一个重载操作符是类成员,那么只有当与他一起使用的左操作数是该类的对象时,该操作符才会被调用。如果该操作符的左操作数必须是其他的类型,则操作符必须被重载为全局名字空间的成员。
②C++要求赋值=,下标[],调用(), 和成员指向-> 操作符必须被定义为类成员操作符。任何把这些操作符定义为名字空间成员的定义都会被标记为编译时刻错误。
③如果有一个操作数是类类型如string类的情形那么对于对称操作符比如等于操作符最好定义为全局名字空间成员。
注意:
1.在增量运算符中,放上一个整数形参,就是后增量运算符,它是值返回,对于前增量没有形参,而且是引用返回,示例:
class Test { public: Test(int x=3){ m_value = x;} Test &operator ++(); //前增量 Test operator ++(int);//后增量 int m_value; }; Test &Test::operator ++() { m_value ++; //先增量 return *this; //返回当前对象 } Test Test::operator ++(int) { Test tmp(*this); //创建临时对象 m_value ++; //再增量 return temp; //返回临时对象 }
int main()
{
Test t1, t2;
cout << t1.m_value << " " << t2.m_value << endl;
cout << (t1++).m_value << " " << (++t2).m_value << endl;
system("pause");
return 0;
}
//所以前增量比后增量效率高
2.operator-> 的返回值必须为一个指针或可以应用 -> 操作的类型.
3. 如果 operator-> 的返回的不是一个指针, C++ 会继续在返回类型上应用 -> 直到得到一个指针为止.
编写程序的时候,想让一个对象表现的像一个指针,因此需要重载->运算符。
class A { public: int i; A(){ i = 100; } void print(int a){ printf("%d/n", a); } A& operator->(){ return *this; } }; int main() { int ret; A a; ret = a->i;//编译不通过 a->print(200);//编译不通过 }
重载->运算符一定是一个成员函数,它有额外的、非典型的限制:它必须返回一个对象(或对象的引用),该对象也有一个重载->运算符的函数,该函数返回一个指针;或者必须返回一个指针,被用于选择重载->箭头所指向的内容。
class A { public: int i; A(){ i = 100; } void print(int a){ printf("%d/n", a); } A* operator->(){ return this; } }; int main() { int ret; A a; ret = a->i; a->print(200); }