个人网站免费申请注册,在网站加上一个模块怎么做,免费软件电视剧,搭建网上商城目录
运算符重载的基本概念
重载加号运算符()
类内实现
类外实现
运算符重载碰上友元函数
可重载和不可重载的运算符
可重载的运算符
不可重载的运算符
重载自加自减运算符(a a)
智能指针
重载等号运算符#xff08;#xff09;
重载等于和不等运算符#xff08…目录
运算符重载的基本概念
重载加号运算符()
类内实现
类外实现
运算符重载碰上友元函数
可重载和不可重载的运算符
可重载的运算符
不可重载的运算符
重载自加自减运算符(a a)
智能指针
重载等号运算符
重载等于和不等运算符 ! 运算符重载的基本概念
概念
运算符重载与函数重载比较类似相当于让一个运算符具有另外一种含义
语法
定义重载的运算符就像定义函数只是该函数的名字是 operator,这里的代表了被重载的运算符。函数的参数中参数个数取决于两个因素。运算符是一元(一个参数)的还是二元(两个参数)运算符被定义为全局函数(对于一元是一个参数对于二元是两个参数)还是成员函数(对于一元没有参数对于二元是一个参数-此时该类的对象用作左耳参数)
重载加号运算符()
类内实现
#include iostreamusing namespace std;class person
{public:person(int age){this-age age;}person operator(person p2)//{person p (this-agep2.age);return p;}int age;
};
void test01()
{person p1(10);person p2(20);person p3 p1 p2;cout p3.age endl;}
int main()
{test01();return 0;
}
类外实现
#include iostreamusing namespace std;class person
{public:person(int age){this-age age;}int age;
};person operator(person p1,person p2)//
{person p (p1.agep2.age);return p;
}void test01()
{person p1(10);person p2(20);person p3 p1 p2;cout p3.age endl;}
int main()
{test01();return 0;
}运算符重载碰上友元函数
将左移运算符的重载函数声明为类的友元函数 就可以访问类的成员
#include iostreamusing namespace std;class person
{friend ostream operator(ostream cout,person p);public:person(int age){this-age age;}private:int age;
};ostream operator(ostream cout,person p)
{cout p.age;return cout;
}void test01()
{person p1(10);cout p1 endl;}
int main()
{test01();return 0;
}
可重载和不可重载的运算符 几乎c 中所有的运算符都可以重载但运算符重载的使用时相当受限制的。特别是不能使用c 中当前没有意义的 运算符( 例如用 ** 求幂 ) 不能改变运算符优先级不能改变运算符的参数个数。这样的限制有意义否则所有这些行为产生的运算符只会混淆而不是澄清寓语意。 可重载的运算符 不可重载的运算符 重载自加自减运算符(a a)
a是先把a赋值到一个临时空间再对a1赋值给临时变量等运算结束后才返回临时变量给a (参与运算的是自加之前的值)
a是先给a1,直接对a赋值不需要开辟临时空间参与运算的是返回值的引用
前置返回的是引用
后置返回的是对象
前置调用void operator()
后置调用myint operator(int) 后置多了一个占位参数
#include iostreamusing namespace std;class myint
{public:myint operator(){this-num this-num1;return *this;}myint(int num){this-num num;}myint operator(int){myint tmp *this;this-num this-num1;return tmp;}int num;
};ostream operator(ostream cout,myint p)
{cout p.num;return cout;
}#include iostreamusing namespace std;class myint
{public:myint operator(){this-num this-num1;return *this;}myint(int num){this-num num;}myint operator(int){myint tmp *this;this-num this-num1;return tmp;}int num;
};ostream operator(ostream cout,myint p)
{cout p.num;return cout;
}void test01()
{myint p1(10);cout p1 endl;p1;//调用operator(p1)或者p1.operator()cout p1 endl;p1;//cout p1 end; //有些编译器会报错cout p1 endl;
}
int main()
{test01();return 0;
}智能指针
我们经常new出一个对象忘记释放所以我们使用智能指针来维护
智能指针实质上是一个局部对象 这个局部对象维护了new出来的对象的地址在局部对象的析构函数中会帮忙释放new出来的对象
对于智能指针我们重载了-和* 让智能指针和普通指针一样使用
#include iostreamusing namespace std;class person
{public:person(int age ){this-age age;}int age;
};class SmartPointer
{public:SmartPointer(person *p1){this-p p1;}~SmartPointer(){delete p;cout 释放了p endl;}person *p;
};void test01()
{//局部对象 在释放之前可以帮助释放pperson *p new person(10);SmartPointer s1(p);cout p-age endl;cout
}
int main()
{test01();return 0;
}重载等号运算符
编译器默认给每个类加上了四个函数 默认的无参构造 默认的拷贝构造 析构函数 operator()
#include iostream
#include string.husing namespace std;class person
{public:person(){}person(int agel,char *namel){age agel;name new char[strlen(namel)1];strcpy(name,namel);}person operator(person p1){this-age p1.age;this-name new char[strlen(p1.name)1];strcpy(this-name,p1.name);return *this;//返回p2 为什么不返回p1可以连续赋值 p3 p2 p1}~person(){delete []name;}int age;char *name;
};void test01()
{person p1(10,(char *)bob);person p2;p2 p1;//p2.operator(person p1)cout p2.age p2.name endl;
}int main()
{test01();return 0;
}重载等于和不等运算符 !
#include iostream
#include string.husing namespace std;class person
{public:person(){}bool operator(person p2){return this-age p2.age this-name p2.name;}bool operator!(person p2){return this-age ! p2.age || this-name ! p2.name;}person(int age,string name){this-age age;this-name name;}int age;string name;
};void test01()
{person p1(10,lucy);person p2(10,bob);if(p1 p2){cout p1 p2 endl;}if(p1 ! p2){cout p1 ! p2 endl;}
}int main()
{test01();return 0;
}
函数调用符号()重载
一个类中重载了的类那么类的定义出来的对象可以像函数一样使用本质是调用了operator()这个函数
#include iostream
#include string.husing namespace std;class Myadd
{public:int add(int a,int b){return a b;}int operator()(int x,int y){return x y;}
};void test01()
{Myadd p;cout p.add(3,5) endl;//p() 可以像函数一样调用的对象 函数对象cout p(3,4) endl;//p.operator()(3,4)cout Myadd()(3,4) endl;//定义一个匿名对象 Myadd().operator()(3,4)
}int main()
{test01();return 0;
}
尽量不要重载 || 不能重载 operator 和 operator|| 的原因是无法在这两种情况下实现内置操作符的完整语义。说得更具体一 些内置版本版本特殊之处在于内置版本的 和 || 首先计算左边的表达式如果这完全能够决定结果就无需计算右边的表达式了-- 而且能够保证不需要。我们都已经习惯这种方便的特性了。 我们说操作符重载其实是另一种形式的函数调用而已对于函数调用总是在函数执行之前对所有参数进行求值。 class Complex{ public : Complex( int flag) { this -flag flag; } Complex operator (Complex complex) { this -flag this -flag complex.flag; return * this ; } bool operator (Complex complex) { return this -flag complex.flag; } public : int flag; }; int main(){ Complex complex1( 0 ); //flag 0 Complex complex2( 1 ); //flag 1 //原来情况应该从左往右运算左边为假则退出运算结果为假 //这边却是先运算 complex1complex2 导致 complex1 的 flag 变为 complex1complex2 的值complex1.a 1 // 1 1 //complex1.operator(complex1.operator(complex2)) if (complex1 (complex1 complex2)) { //complex1.operator(complex2) cout 真 ! endl; } else { cout 假 ! endl; } return EXIT_SUCCESS; } 符号重载总结 1., [], () 和 - 操作符只能通过成员函数进行重载 例如 p 3 成员函数实现 p.operator(3) 全局函数实现 operator(3,p) 如果把3写在左边 相当于 3 p将p赋值给3但3是一个常量常量不能作为左值 2. 和 只能通过全局函数配合友元函数进行重载 例如cout p 因为要把cout放在操作符的左侧 不可能去修改标准库中的类 所以必须配合全局函数和友元函数进行重载 3.不要重载 和 || 操作符因为无法实现短路规则 内置版本的 和 || 首先计算左边的表达式 常规建议