运算符重载
目的:简化操作,让已有运算符适应不同类型的数据。
语法:函数的名字由关键字operator及其紧跟的运算符组成
例如:“+”运算符的重载:operator+
运算符<<的重载(?全局函数作为友元,完成运算符重载)
#include <iostream>
#include <string.h>
using namespace std;
class Mem{
//设置重载函数为友元函数
friend void operator<<(ostream &out, Mem &P);
private:
char* name;
int age;
public:
Mem(char* name, int age){
this->name = new char[strlen(name)+1];
// this->name = name;
strcpy(this->name, name);
this->age = age;
}
~Mem(){
if(this->name != NULL){
delete [] this->name;
this->name = NULL;
}
}
void Print(){
cout << "name: " << this->name <<endl;
cout << "age: " << this->age << endl;
}
};
void operator<<(ostream &out, Mem &P){
out << "name: " << P.name << endl;
out << "age: " << P.age << endl;
}
int main()
{
Mem Lucy("lucy", 18);
//调用普通成员函数遍历对象
Lucy.Print();
cout << endl;
//cout默认输出方式,无法输出对象,无法识别自定义对象格式
// cout << Lucy << endl;
// cout << Lucy.Print() << endl;
//重载<<
//运算符重载的调用方式1:
operator<<(cout, Lucy);
cout << endl;
//运算符重载的调用方式2:
/*对方法1的优化,去掉operator
第一个参数放在运算符<<的左边
第二个参数放在运算符<<的右边
*/
cout << Lucy;
return 0;
}
?升级版
返回cout的引用,可以实现迭代操作
#include <iostream>
#include <string.h>
using namespace std;
class Mem{
//设置重载函数为友元函数
friend ostream& operator<<(ostream &out, Mem &P);
private:
char* name;
int age;
public:
Mem(char* name, int age){
this->name = new char[strlen(name)+1];
// this->name = name;
strcpy(this->name, name);
this->age = age;
}
~Mem(){
if(this->name != NULL){
delete [] this->name;
this->name = NULL;
}
}
void Print(){
cout << "name: " << this->name <<endl;
cout << "age: " << this->age << endl;
}
};
ostream& operator<<(ostream &out, Mem &P){
out << "name: " << P.name << endl;
out << "age: " << P.age << endl;
return cout;
}
int main()
{
Mem Lucy("lucy", 18);
Mem Rex("rex", 20);
//可以实现迭代操作
cout << Lucy << Rex << endl;
return 0;
}
?运算符+的重载(全局函数作为友元,完成运算符重载)
#include <iostream>
#include <string.h>
using namespace std;
class Mem{
//设置重载函数为友元函数
friend ostream& operator<<(ostream &out, Mem &P);
friend Mem operator+(Mem &P1, Mem &P2);
private:
char* name;
int age;
public:
Mem(char* name, int age){
this->name = new char[strlen(name)+1];
// this->name = name;
strcpy(this->name, name);
this->age = age;
}
~Mem(){
if(this->name != NULL){
delete [] this->name;
this->name = NULL;
}
}
void Print(){
cout << "name: " << this->name <<endl;
cout << "age: " << this->age << endl;
}
};
ostream& operator<<(ostream &out, Mem &P){
out << "name: " << P.name << endl;
out << "age: " << P.age << endl;
return cout;
}
Mem operator+(Mem &P1, Mem &P2){
char* name = new char[strlen(P1.name)+strlen(P2.name)+1];
name = strcat(P1.name, P2.name);
int age = P1.age + P2.age;
Mem N(name, age);
if(name != NULL){
delete [] name;
name = NULL;
}
return N;
}
int main()
{
Mem Lucy("lucy", 18);
Mem Rex("rex", 20);
//可以实现迭代操作
Mem New = Lucy + Rex;
cout << New << endl;
return 0;
}
??运算符+的重载(成员函数完成运算符重载)
#include <iostream>
#include <string.h>
using namespace std;
class Mem{
//设置重载函数为友元函数
friend ostream& operator<<(ostream &out, Mem &P);
private:
char* name;
int age;
public:
Mem(char* name, int age){
this->name = new char[strlen(name)+1];
// this->name = name;
strcpy(this->name, name);
this->age = age;
}
~Mem(){
if(this->name != NULL){
delete [] this->name;
this->name = NULL;
}
}
void Print(){
cout << "name: " << this->name <<endl;
cout << "age: " << this->age << endl;
}
//成员函数完成运算符重载
Mem operator+(Mem &P2){
char* name = new char[strlen(this->name)+strlen(P2.name)+1];
name = strcat(this->name, P2.name);
int age = this->age + P2.age;
Mem N(name, age);
if(name != NULL){
delete [] name;
name = NULL;
}
return N;
}
};
ostream& operator<<(ostream &out, Mem &P){
out << "name: " << P.name << endl;
out << "age: " << P.age << endl;
return cout;
}
int main()
{
Mem Lucy("lucy", 18);
Mem Rex("rex", 20);
//方法1
// Mem New = Lucy.operator+(Rex);
//方法2
Mem New = Lucy + Rex;
cout << New << endl;
return 0;
}
?
自增和自减运算符的重载?
自增运算符的重载
#include <iostream>
#include <string.h>
using namespace std;
class Mem{
friend ostream& operator<<(ostream &out, Mem &P);
private:
int a;
int b;
public:
Mem(int a, int b):a(a), b(b){}
~Mem(){}
//成员函数完成运算符重载
//重载前置++,先+,后使用
//编译器默认识别operator++(a),使用成员函数作为重载可用this,因此可简化为operator++()
Mem& operator++(){
//先加
a++;
b++;
//后使用
return *this;
}
//重载后置++,先使用,后+
//编译器默认识别operator++(a, int),使用成员函数作为重载可用this,因此可简化为operator++(int)
Mem operator++(int){
//先加
Mem old(a, b);
a++;
b++;
//后使用
return old;
}
};
ostream& operator<<(ostream &out, Mem &P){
out << "a: " << P.a << endl;
out << "b: " << P.b << endl;
return cout;
}
int main()
{
Mem age(20, 18);
cout << ++age;
cout << endl;
Mem b = age++;
cout << b;
cout << endl;
cout << age;
return 0;
}
自减运算符的重载(和自增运算符的重载相似)
指针运算符(*, ->)的重载
#include <iostream>
#include <string.h>
using namespace std;
class Age{
private:
int num;
public:
Age(int num): num(num){
cout << "GZ_age= " << num << endl;
}
void show(){
cout << "age= " << num << endl;
}
~Age(){
cout << "XG_age= " << num << endl;
}
};
class Pointer{
public:
Age* age;
public:
Pointer(Age* age): age(age){
cout << "GZ2" << endl;
age->show();
}
~Pointer(){
age->show();
if(age != NULL){
delete this->age;
this->age = NULL;
cout << "XG2" << endl;
}
}
Age* operator->(){
return this->age;
}
Age& operator*(){
return *(this->age);
}
};
int main()
{
Age A(1);
//B指针并没有被释放,需要 delete B;
Age* B = new Age(2);
//可以自动设置指针并释放
Pointer C(new Age(3));
//想要访问Age类中的show()函数
//C.age->show();
//使用重载的->简化C.age->show();
C->show();
//等于(C.operator->())->show();
//使用重载的*简化访问show();
(*C).show();
return 0;
}
赋值运算符(=)的重载(重要)
前提1:类中无指针成员不需要重载=运算符
#include <iostream>
using namespace std;
class Arr{
public:
int a;
int b;
public:
Arr(): a(0), b(0){
cout << "WC_GZ" << endl;
}
Arr(int a, int b): a(a), b(b){
cout << "YG_GZ" << endl;
}
Arr(const Arr &arr): a(arr.a), b(arr.b){
cout << "KB_GZ" << endl;
}
~Arr(){
cout << "XGHS" << endl;
}
void show(){
cout << "a= " << a << " b= " << b << endl;
}
};
int main()
{
Arr A(1, 2);
A.show();
//这里A对B赋值调用的拷贝构造函数,这里=并不是赋值运算符=
Arr B = A;
B.show();
Arr C;
//此处的=才是赋值运算符,默认的赋值=运算符调用的浅拷贝
C = A;
C.show();
return 0;
}
前提2:类中有指针成员必须重载=运算符
?默认拷贝函数会出现断点错误
#include <iostream>
#include <string.h>
using namespace std;
class Name{
public:
char* name;
public:
Name(){
name = NULL;
cout << "WC_GZ" << endl;
}
Name(char* name){
this->name = new char(strlen(name)+1);
cout << "YG_GZ" << endl;
}
~Name(){
cout << "XGHS" << endl;
}
void show(){
cout << "name= " << name << endl;
}
};
int main()
{
Name A("ucy");
A.show();
//默认的拷贝构造函数,是浅拷贝
Name B = A;
B.show();
Name C;
//默认的赋值=运算符调用的浅拷贝
C = A;
C.show();
return 0;
}
自定义拷贝构造函数避免断点错误?
#include <iostream>
#include <string.h>
using namespace std;
class Name{
public:
char* name;
public:
Name(){
name = NULL;
cout << "WC_GZ" << endl;
}
Name(char* name){
this->name = new char[strlen(name)+1];
cout << "YC_GZ" << endl;
}
Name(const Name &n){
this->name = new char[strlen(n.name)+1];
strcpy(this->name, n.name);
cout << "KB_GZ" << endl;
}
~Name(){
cout << "XGHS" << endl;
}
void show(){
cout << "name= " << name << endl;
}
};
int main()
{
Name A("ucy");
A.show();
//自定义的拷贝构造函数
Name B = A;
B.show();
return 0;
}
重载赋值运算符=
#include <iostream>
#include <string.h>
using namespace std;
class Name{
public:
char* name;
public:
Name(){
name = NULL;
cout << "WC_GZ" << endl;
}
Name(char* name){
this->name = new char[strlen(name)+1];
cout << "YC_GZ" << endl;
}
Name(const Name &n){
this->name = new char[strlen(n.name)+1];
strcpy(this->name, n.name);
cout << "KB_GZ" << endl;
}
~Name(){
cout << "XGHS" << endl;
}
void show(){
cout << "name= " << name << endl;
}
Name& operator=(Name &n){
if(this->name != NULL){
delete [] this->name;
this->name = NULL;
}
this->name = new char[strlen(n.name)+1];
strcpy(this->name, n.name);
return *this;
}
};
int main()
{
Name A("ucy");
A.show();
//自定义的拷贝构造函数
Name B = A;
B.show();
Name C, D, E;
//可迭代重载=运算符
E = D = C = A;
C.show();
D.show();
E.show();
return 0;
}
等于和不等于运算符重载(==,!=)
#include <iostream>
#include <string.h>
using namespace std;
class Name{
public:
char* name;
public:
Name(){
this->name = NULL;
}
Name(char* name){
this->name = new char[strlen(name)+1];
strcpy(this->name, name);
}
~Name(){
if(this->name != NULL){
delete [] this->name;
this->name = NULL;
}
}
bool operator==(Name &n){
if(strcmp(this->name, n.name) == 0){
return true;
}
if(strcmp(this->name, n.name) != 0){
return false;
}
}
bool operator!=(Name &n){
if(strcmp(this->name, n.name) != 0){
return true;
}
if(strcmp(this->name, n.name) == 0){
return false;
}
}
};
int main()
{
Name A("lucy");
Name B("lucy");
Name C("rex");
if(A==B){
cout << "A==B" << endl;
}
if(A!=B){
cout << "A!=B" << endl;
}
if(A==C){
cout << "A==C" << endl;
}
if(A!=C){
cout << "A!=C" << endl;
}
return 0;
}
函数调用符()的重载(仿函数)
#include <iostream>
using namespace std;
class F{
public:
int add(int x, int y){
return x+y;
}
//重载(),第一个()是重载的符号,第二个()为了传参
int operator()(int x, int y){
return x+y;
}
};
int main()
{
F f;
cout << f.add(1, 2) << endl;
//重载()
cout << f.operator()(1, 2) << endl;
//简化 f和()结合,会自动寻找()运算符
//此处f(1, 2)不是一个真正的函数,仅仅是对象名和()结合,调用()重载运算符而已
//f不是函数名 只是f(1, 2)类似于函数调用,所以将f(1, 2)称为仿函数
cout << f(1, 2) << endl;
//F是类名称
//F()是匿名对象
cout << F()(1, 2) << endl;
return 0;
}
?
?
期望结果为假,但实际结果为真?
强化训练 字符串类 (重要)?
字符串类包含字符串与字符串的操作
main.cpp
#include <iostream>
#include <mystring.h>
using namespace std;
int main()
{
Mystring A("lucy");
//重载<<
cout << A;
//重载>>
// Mystring B;
// cin >> A;
// cin >> B;
// cout << B << A;
//重载[]
cout << A[3] << endl;
A[2] = 'b';
cout<<A;
return 0;
}
mystring.cpp
#include "mystring.h"
#include <iostream>
#include <string.h>
using namespace std;
Mystring::Mystring(){
this->s = NULL;
this->size = 0;
}
Mystring::Mystring(const char* s){
this->s = new char[strlen(s)+1];
strcpy(this->s, s);
this->size = strlen(this->s);
}
Mystring::Mystring(const Mystring &s){
if(this->s != NULL){
delete [] this->s;
this->s = NULL;
}
this->s = new char[s.size+1];
strcpy(this->s, s.s);
this->size = s.size;
}
Mystring::~Mystring(){
if(this->s != NULL){
delete [] this->s;
this->s = NULL;
}
}
//重载[]
char &Mystring::operator[](int index){
if(index < 0 || index > this->size){
cout << "out of space" << endl;
}
else{
return this->s[index-1];
}
}
//void Mystring::operator=(char n){
//}
//重载<<
ostream& operator<<(ostream &out, Mystring &T){
out << "Str: " << T.s << ", Size: " << T.size << endl;
return out;
}
//重载>>
istream& operator>>(istream &in, Mystring &T){
if(T.s != NULL){
delete [] T.s;
T.s = NULL;
}
char d[1024] = "";
in >> d;
T.size = strlen(d);
T.s = new char[T.size+1];
strcpy(T.s, d);
return in;
}
mystring.h
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
using namespace std;
class Mystring
{
friend ostream& operator<<(ostream &out, Mystring &T);
friend istream& operator>>(istream &in, Mystring &T);
private:
char* s;
int size;
public:
Mystring();
Mystring(const char* s);
Mystring(const Mystring &s);
~Mystring();
char &operator[](int index);
// void operator=(char n);
};
#endif // MYSTRING_H
注:仅用于学习总结
QT学习C++(11)_爱吃糖葫芦的大熊的博客-CSDN博客
QT学习C++(13)_爱吃糖葫芦的大熊的博客-CSDN博客
|