之前看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<
今天还弄明白了,强制类型转换的本质函数调用关系是什么
(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"))