赞
踩
加法运算符重载
分别可以通过成员函数,全局函数进行
#include <iostream> using namespace std; class Person { public: //第一种成员函数重载 Person operator+(Person &p) { Person temp; temp.m_A = this->m_A + p.m_A; temp.m_B = this->m_B + p.m_B; return temp; } public: int m_A; int m_B; }; //第二种全局函数重载 Person operator+(Person &p1,Person &p2) { Person temp; temp.m_A = p1.m_A + p2.m_B; temp.m_B = p1.m_B + p2.m_B; return temp; } void test() { Person p1; p1.m_A = 10; p1.m_B = 10; Person p2; p2.m_A = 10; p2.m_B = 10; Person p3; //原本成员函数调用方式为:p3 = p1.operator+(p2) //原本全局函数调用方式为:p3 = operator+(p1,p2) //都可以简化为p3 = p1 + p2 p3 = p1+p2; cout<<"p3.m_A = "<<p3.m_A<<endl; cout<<"p3.m_B = "<<p3.m_B<<endl; } int main() { test(); system("pause"); return 0; }
左移运算符重载
不用成员函数:无法实现cout在左侧
可以用全局函数
试一下使用成员函数写出来,发现不行
class Person
{
public:
void operator<<(ostream &cout) //先定义类再调用,这样的写的话就为p<<cout
{
...
}
...;
}//显然是不行的,那么试一下全局函数
再用全局函数实现
#include <iostream> #include <string> using namespace std; class Person { public: int m_a; int m_b; }; //采用全局函数进行重载 void operator<<(ostream &cout,Person &p) //ostream为标准输出流 { cout<<"m_a = "<<p.m_a<<" m_b = "<<p.m_b; //其中cout也可以改为其他名字 //例:operator<<(ostream &out,Person &p) //然后进行输出 out<<......... } void test() { Person p; p.m_a = 10; p.m_b = 10; cout<<p; } int main() { test(); system("pause"); return 0; }
再试一下cout<<p<<endl;发现报错了
2 IntelliSense: 无法确定需要哪个 重载函数 "endl" 实例
如果还是返回cout,再接上<<endl就可以解决
解决:让全局函数进行返回
ostream & operator<<(ostream &cout,Person &p)
{
cout<<"m_a = "<<p.m_a<<" m_b = "<<p.m_b;
return cout; //这样返回一个cout就能连上<<endl以及其他输出
}
———————————————————————————————————
递增运算符重载
写在成员函数中
分别为前置递增和后置递增
#include <iostream> #include <string> using namespace std; class Myint { friend ostream & operator<<(ostream &cout,Myint &p); public: Myint() { m_int = 0; } //前置++运算符 Myint &operator++() { m_int++; return *this; } //后置++运算符 Myint operator++(int) { Myint temp = *this; m_int++; return temp; } private: int m_int; }; //左移运算符 ostream & operator<<(ostream &cout,Myint &p) { cout<<p.m_int; return cout; } //前置++测试 void test01() { Myint mint; cout<<++(++mint)<<endl; cout<<mint<<endl; //测试两次++后的结果,若成员函数没有&,返回的是值,那么第二次则是开辟新的对象 } //后置++测试 void test02() { Myint mint; cout<<mint++<<endl; cout<<mint<<endl; //测试完成后置++运算 } int main() { test02(); system("pause"); return 0; }
———————————————————————————————————
赋值运算符重载
#include <iostream> #include <string> using namespace std; class Person { public: Person(int age) { m_age = new int(age); } int *m_age; //定义一个指针 }; void test01() { Person p1(10); Person p2(20); p1 = p2; //试着直接运行通过了 cout<<"p1的年龄为:"<<*p1.m_age<<endl; cout<<"p2的年龄为: "<<*p2.m_age<<endl; } int main() { test01(); system("pause"); return 0; }
这里进行运行直接通过了,我们再在成员函数中加一个析构函数进行释放内存
~Person() //写一下析构函数,并且释放指针指向内存
{
if(m_age != NULL)
{
delete m_age;
m_age = NULL;
}
}
再运行一下发现程序直接崩了,原因是原本系统给我们的类中的拷贝构造函数是进行的浅拷贝,到后面进行赋值过后,两个指针同时指向同一个内存
,当第一个指向的内存地址为空,再进行释放,那么就会出现问题
解决办法:自己写一个拷贝构造函数,只不过是内部是进行深拷贝
//写一个赋值 运算符成员函数在类中
void operator=(Person &p)
{
if(m_age != NULL) //判断指针指的地址是否为空
{
delete m_age; //手动进行释放内存
m_age = NULL;
}
//浅拷贝写法 m_age = p.m_age,也就是系统给我们写得
m_age = new int(*p.m_age); //开辟新的内存空间给m_age,也就是深拷贝
}
此时运行通过
那当我们再创建一个对象
Person p3(30) //在test01中
p3 = p2 = p1 //此时再运行程序
1 IntelliSense: 没有与这些操作数匹配的 "=" 运算符
分析:此时我们应当为自己写的拷贝构造函数增添一个返回值 使p3 等于一个对象,而不是空 (在进行p2 = p1时,函数并没有返回什么,是void类型,那么就会出错)
解决:
//写一个赋值 运算符函数
Person &operator=(Person &p)
{
if(m_age != NULL) //判断指针指的地址是否为空
{
delete m_age; //手动进行释放内存
m_age = NULL;
}
//浅拷贝写法 m_age = p.m_age,也就是系统给我们写得
m_age = new int(*p.m_age); //开辟新的内存空间给m_age,也就是深拷贝
return *this; //*this返回对象本身
}
再进行运行程序,就可以通过了
完整赋值运算符重载代码:
#include <iostream> #include <string> using namespace std; class Person { public: Person(int age) { m_age = new int(age); } ~Person() //写一下析构函数,并且释放指针指向内存 { if(m_age != NULL) { delete m_age; m_age = NULL; } } //写一个赋值 运算符函数 Person &operator=(Person &p) { if(m_age != NULL) //判断指针指的地址是否为空 { delete m_age; //手动进行释放内存 m_age = NULL; } //浅拷贝写法 m_age = p.m_age,也就是系统给我们写得 m_age = new int(*p.m_age); //开辟新的内存空间给m_age,也就是深拷贝 return *this; } int *m_age; }; void test01() { Person p1(10); Person p2(20); Person p3(30); p3 = p2 = p1; //试着直接运行通过了 cout<<"p1的年龄为:"<<*p1.m_age<<endl; cout<<"p2的年龄为: "<<*p2.m_age<<endl; cout<<"p3的年龄为: "<<*p3.m_age<<endl; } int main() { test01(); system("pause"); return 0; }
———————————————————————————————————
关系运算符重置
完整代码:
#include <iostream> #include <string> using namespace std; class Person { public: Person(string name,int age) { this->name = name; this->age = age; } //关系运算符==重置 bool operator==(Person &p) { if(this->name == p.name && this->age == p.age) //进行比较 { return true; } else { return false; } } //关系运算符!=重置 bool operator!=(Person &p) { if(this->name == p.name && this->age == p.age) //进行比较 { return false; } else { return true; } } public: string name; int age; }; void test01() { Person p1("小王",15); Person p2("小王",16); if(p1 == p2) { cout<<"p1与p2相等"<<endl; } else { cout<<"p1与p2不相等"<<endl; } if(p1 != p2) { cout<<"p1与p2不相等"<<endl; } else { cout<<"p1与p2相等"<<endl; } } int main() { test01(); system("pause"); return 0; }
别的关系运算符也差不多
———————————————————————————————————
调用运算符重载
也就是(),又称为仿函数
特点是:没有固定的写法,十分灵活
#include <iostream> #include <string> using namespace std; class Myprint { public: //()运算符重载也可以叫仿函数,没有固定,十分自由 void operator()(string name) //可以只进行输出 { cout<<name<<endl; } }; class Myadd { public: //仿函数,也可以进行相加返回 int operator()(int a,int b) { return a+b; } }; void test01() { Myprint myprint; myprint("天天向上"); } void test02() { Myadd myadd; cout<<myadd(100,200)<<endl; //匿名函数对象 Myadd(),然后在(100,200)使用仿函数 cout<<Myadd()(100,200)<<endl; } int main() { test02(); system("pause"); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。