20170101C++阶段班03_Object C++_05运算符重载

来源:互联网 发布:投影仪网络连接很慢 编辑:程序博客网 时间:2024/06/13 19:12

运算符重载:

1:在构造函数前面加上explicit可以防止隐式转换!

2:operator=函数可以重载!!
    operator后面接的符号就是运算符,对一些运算符进行重载,运算符包括大于小于,=><==!=+-*/&|~!……,加减……包括new/delete/sizeof……都是运算符!

3:不可以重载的运算符:

      有几个运算符是不可以重载的:作用域运算符(::),条件运算符(三目)(?:),点(.)直接成员访问运算符,sizeof运算符,类成员指针(*.),这五个是不可以重载的!!!
4:取地址运算符&也是默认生成的!还有*也是默认的。ClassDemo::operator&(const ClassDemo& other){return *this} ClassDemo *demo = &demo1;//
ClassDemo other = *p;//也是可以的
5:默认函数:

    一个空类当中会生成默认的:构造函数,析构函数,拷贝构造函数,赋值构造函数,operator&,operator*六个默认的函数!!!!!!任何一个类都可以用上面六个默认函数。

6:重载返回值:

      对等号重载不一定一定是返回这个类对象的引用,可以使void,默认的是返回类对象的引用,但不能连等。demo1 = other = 10;默认的他是支持这样连等的,这个与返回值关系非常大!对operator=重载最好返回当前对象的引用比较好。否则语义就不正确了。

Integer& Integer::operator=(const int num)//返回一定是当前对象的引用,否则语义编的不对!{std::cout << "调用operator=(const int)" << _num << std::endl;_num = num;return *this;}main函数中:demo = demo1 = 100;//调用operator=(const int),然后调用operator=(const Integer&)从右到左,            //如果重载的operator=函数返回值不是Integer&,这句就会出错。如果没有重载operator=,就会先隐式转换然后使用默认的//上面那句等于:demo1.operator=(operator=(10));demo = demo1;如果返回值为void,那么就相当于demo = void了,出错!

7:加减等符号的重载都要返回本类,特别不能返回临时对象的引用,特别的不能修改原来对象里面的值。重载加法,如果参数是int型,加法必须对象+数据,不能反过来。如果参数是对象,就是对象+对象。下面是对+号重载:

Integer Integer::operator+(const Integer&other){std::cout << "operator+(const Integer&other)" << _num << std::endl;Integer temp;temp._num = _num + other._num;return temp;//返回值为Integer,在return之前会调用拷贝构造函数创建返回的对象,创建的这个新里面的值全是无效值,然后在拷贝构造函数里面被赋值//,return的时候,temp就会被析构掉。}main函数里面demo2 = demo1 + demo;//在用上面return前拷贝构造函数构造的对象赋值之后,这个对象立即就被析构掉了!最后主函数return 0;后最开始申请的demo,                             //demo1,demo2才会被析构掉。std::cout << demo.GetNum() << demo1.GetNum() << demo2.GetNum() << std::endl;


7:注意:返回值为Integer,在return之前会调用拷贝构造函数创建返回的对象,创建的这个新里面的值全是无效值,然后在拷贝构造函数里面被赋值,return的时候,temp就会被析构掉。//主函数里面在上面重载+函数return前拷贝构造函数构造的对象赋值之后,这个对象立即就被析构掉了!最后主函数return 0;后最开始申请的demo,demo1,demo2才会被析构掉。(重载的+号,不能改变任何一个参与运算的对象里面的任何一个值,否则就不符合语义。)

8:如果重载的加法为Integer Integer::operator+(const int num){}//那么就只可以使用对象+int数据,不可以为int数据+对象。这里引入友元函数!

以friend开头的友元函数才可以实现反过来加。
friend Integer operator+(int num, Integer& me){Integer temp;//类构造函数的默认参数要么写在.h文件声明处,要么写在.cpp实现方法处,但这个友元函数必须写在.h文件里面,所以默认参数写                             //在.h文件里面这句话才编译不会出错,当然,构造函数如果没有参数也是可以的!temp._num = num + me._num;//不会修改mereturn temp;}//友元函数不属于这个类,不能写在这个类的.cpp文件里面,只能写在.h文件里面,

 

   这个函数并不属于这个类的成员函数,它属于友元,虽然他写在这个class里面,但他不属于这个类里面的成员函数,友元是一种特殊机制。在主函数里面,demo.后面的提示类方法是不会出现这个函数的,友元主要用于运算符的重载!  现在调用100+other;//可以了,返回值不为void就可以了。在友元函数存在的时候demo = 100+demo1+1000;//这个会分别调用friend+,operator+,赋值函数。不会修改任何一个已有对象的值。如果一个函数(f())里面产生临时对象主函数里面直接Integer i = f();,这个临时对象就不会被析构掉。

9:函数返回值与构造,析构,拷贝构造,赋值调用的时间

Integer f1()//Integer是自己写的一个类{return Integer(666);//直接返回构造的对象,}Integer f2(){Integer f2(667);return f2;//返回构造对象前会拷贝构造一个新的返回,并返回后析构f2}Integer& f3(){return Integer(777);//warning C4172: 返回局部变量或临时变量的地址,有风险操作!!}//主函数里面的类容Integer demo1(20);//调用构造函数Integer demo3 = f1();//f1()调用构造函数,是安全的demo1 = f1();//f1()构造,demo1调用operate=(const Integer&other),然后析构f1()对象,是安全的Integer demo4 = f2();//f2()调用构造函数并调用拷贝构造函数拷贝一个临时的,返回这个临时的对象,析构f2()里面的临时对象,是安全的demo1 = f2();//和上面一个相同的步骤,然后还会多调用一个operate=(const Integer&other),并析构f2()返回值的临时对象,是安全的Integer demo5 = f3();//f3()调用构造函数,析构对象,拷贝构造(这里拷贝构造的对象没有数据,是存在风险的)。demo1 = f3();//构造,析构对象,然后调用operate=(const Integer&other),也是有风险操作。//执行完后demo1和demo5里面的值是未定义的!



10:对++重载的话

    一个有参数,一个无参数,有无参数是用来区分他是前++还是后++。带参的是后++,无参的是前++。后++比较复杂,因该使用临时对象,同时因该返回这个临时对象的拷贝,而不可以返回临时对象的引用,因为这个临时对象在return的时候会被析构掉!!返回临时对象会在外部操作完成时候在析构这个对象,返回临时引用是本函数内return的时候(用完时)直接就析构了。

Integer & Integer::operator++()//前++{std::cout << "operator++()" << std::endl;++_num;return *this;}Integer Integer::operator++(int)//后++{std::cout << "operator++(int)" << std::endl;Integer temp;++temp._num;this->_num++;return temp;//需返回临时对象,与上面说的一样。这里也会调用拷贝构造函数。然后立刻析构temp。拷贝构造函数拷贝的对象用于外面使用!}
cout<<cin>>,也是运算符,称为流运算符。<<为流出符,>>流进符。也可以被重载。
friend std::ostream& operator<<(std::ostream &os, const Integer &me){//第一个参数不可以加const,因为返回os对象的引用,os内部会进行改变os << me._num;return os;//返回值必须为引用,传进来的参数也是引用,否则error C2280:  尝试引用已删除的函数}friend std::istream& operator>>(std::istream &is, Integer &me)//第二个不能为const,因为会改变!{is >> me._num;return is;}//主函数直接调用。std::cout << demo2 << std::endl;

1 0
原创粉丝点击