关于C++的连续运算符重载

之前看mxnet,奇怪为什么可以写写成这个样子

load.add_attr("xxx",1)
    .get_add()
    .add_attr()
    .simplify()

cout<<"xxx"
    <<"ddd"
    <<"xxx"

后面我才明白,这些方法返回是这个类对象本身(return *this),所以可以一直用.来调用新的方法,或者重复调用一个方法

而流插入运算符也一样,cout是ostream类的一个对象,这个操作符返回的是ostream类本身,所以可以一直调用operator <<. 我们要看到它本质的函数调用形式是

> cout.operator<<(5).operator<<("xxx")

Demo& add_attr(){
   xxx
   return *this;
}

而流插入运算符是 5+c一样,成员函数不够用,要加要加到int类里面去,但这个类早就写好,现在是要加到我们写的复数类里面去,怎么办呢,只能加为全局函数,需要写出友元函数才够用

os.operator<<(Demo)demo里面可以写一个

friend ostream& operator<<(ostream& os, const Demo& c){

os<<c.real<<"+i"<<c.img;

return os;

}

今天还弄明白了,强制类型转换的本质函数调用关系是什么

(double)c   等价于 c.opeator double()

重载强制类型转换运算符:成员函数,单目运算,没有返回值和参数值

operator double(){return this->real;}

从设计者的角度去思考问题

object.operator++() --效率高的

++obj (返回修改后的值)

obj++ (返回修改前的值),看object在哪个未知,前还是后,来决定返回的是前还是后的值

这两种的本质函数调用关系都是obj.opeator++(),区分不出前置和后置,因此,编译器决定多写一个没用的int参数来区别。在实现的过程中,还可以发现哪一种实现效率低一些;要保留一个temo原值效率低一些。++i效率高一些。

然后我在实践的过程中有一个问题

class Demo
{
  public:
    int x;
    Demo( int n ) : x( n ) {}
    Demo operator++()
    // ++i
    {
        x += 1;
        return *this;
    }
    Demo& operator++( int )
    // i++ 为什么这个返回类型 不能加引用& ???
    {
        Demo tmp = *this;
        x += 1;
        return tmp;
    }
    friend ostream& operator<<( ostream& os, const Demo& c )
    {
        os << c.x << "\n";
        return os;
    }
};
int main()
{
    Demo d( 10 );
    cout << ( d++ ) << "\n";
    cout << d << "\n";
    return 0;
}

main.cpp:21:16: warning: reference to local variable 'tmp' returned [-Wreturn-local-addr]
   21 |         return tmp;

我不明白为什么这个返回类型不能是引用,编译的时候提示,引用一个函数内部的local variable是由问题的。

MOOC的课程老师讲解说,(++a)这种高效实现,返回的一个引用,结果可以放在等号左边,对其引用的对象进行赋值。

( ++a ) = 100;

依稀记得函数返回值引用可以这样用

func()=10;

我调查总结,什么情况下返回值是引用,什么情况下返回值不是应用。参数的话,如果内容要改变,就用引用,不改变加const, 返回如果希望可以连用,用于左值,需要用引用,这样可以进行赋值。

complex operator+(complex& a)

complex& operator++(){return *this}  (++a)=10;

complex& operator=(const complex& a){return *this} 本质原因是赋值运算符是可以连用的,所以返回引用 a=b="hello"   a.operator=(b.operator=("hello"))

猜你喜欢

转载自blog.csdn.net/Chunying27/article/details/128491586
今日推荐