返回值与临时量
#if 0
/*
返回值规则:
1.类类型
都是以临时量带回及原因
2.其他类型
字节数 <=4 由eax寄存器带回
>4 <=8 由eax 和edx 寄存器带回
>8 由临时量带回
*/
class Test
{
public:
Test(int a=10):ma(a)
{
cout<<"Test::Test(int)"<<endl;
}
Test(const Test& rhs):ma(20)
{
cout<<"Test::Test(Test)"<<endl;
}
//const Test * const
int getValue()const
{
return ma;
}
void show()
{
getValue();
cout<<"ma"<<ma<<endl;
}
~Test()
{
cout<<"Test::~Test()"<<endl;
}
private:
int ma;
};
Test Getval(Test rhs)
{
Test temp=rhs;
return temp;
}
int main()
{
Test test1(20);
Getval(test1).show();
}
/*
以对象类型返回,不管几个字节 都是由临时量带回来
为什么?
代码----》》 Test test1(20);
Getval(test1).show();
打印---》》》 Test::Test(int)
Test::Test(Test)
Test::Test(Test)
Test::Test(Test)
Test::~Test()
Test::~Test()
ma20
Test::~Test()
Test::~Test()
Getval全局函数结束后返回了一个临时对象
用临时对象调用show函数
之所以用临时对象返回 而不用寄存器返回
是因为寄存器不能取地址 ,而对象调用成员方法需要把对象地址传给
this指针所以只能以临时量的方式返回,临时对象是存放在内存中,
通过返回值已经知道了类型 就是一个显式生成临时对象
存放在内存中 相当于一个普通的变量
Test::Test(int) Test test1;
Test::Test(Test) Test rhs=test1;
Test::Test(Test) Test temp=rhs;
Test::Test(Test) 以临时对象返回
空类问题
空类
class Node
{
public:
void show()
{
cout<<"hello"<<endl;
}
};
gcc中空的结构体是0
那么空类的字节为什么是1?
因为用对象调用成员方法的时候需要传递对象地址给this指针,
0是没有地址的, 所以最少需要1个字节大小的地址
*/
返回临时量的几种情况
-
显式生成临时对象是为了生成新的对象(即为了生成 作返回值用途 的临时对象);
class Test { public: Test(int a=10):ma(a) { cout<<"Test::Test(int)"<<endl; } Test(const Test& rhs):ma(20) { cout<<"Test::Test(Test)"<<endl; } //const Test * const int getValue()const { return ma; } void show() { getValue(); cout<<"ma"<<ma<<endl; } ~Test() { cout<<"Test::~Test()"<<endl; } private: int ma; }; Test Getval(Test& rhs) { return Test(rhs); } int main() { Test test1(20); Getval(test1); } /* Test::Test(int) Test::Test(Test) Test::~Test() Test::~Test() return Test(rhs); */
-
Test(rhs);显示生成了临时对象,然后显式生成临时对象的方式 优化生成 作返回值用途的临时对象
又因为main函数 Test test2=Getval(test1) 又以生成作返回用途的临时对象的方式 来优化生成 test2class Test { public: Test(int a=10):ma(a) { cout<<"Test::Test(int)"<<endl; } Test(const Test& rhs):ma(20) { cout<<"Test::Test(Test)"<<endl; } //const Test * const int getValue()const { return ma; } void show() { getValue(); cout<<"ma"<<ma<<endl; } ~Test() { cout<<"Test::~Test()"<<endl; } private: int ma; }; Test Getval(Test& rhs) { return Test(rhs); } int main() { Test test1(20); Test test2=Getval(test1); }
-
不能返回局部变量的指向或者引用
Test test2=Getval(test1);
Test& Getval(Test& rhs){return Test(rhs);}
返回的是局部对象地址class Test { public: Test(int a=10):ma(a) { cout<<"Test::Test(int)"<<endl; } Test(const Test& rhs):ma(20) { cout<<"Test::Test(Test)"<<endl; } //const Test * const int getValue()const { return ma; } void show() { getValue(); cout<<"ma"<<ma<<endl; } ~Test() { cout<<"Test::~Test()"<<endl; } private: int ma; }; Test& Getval(Test& rhs) { return Test(rhs); } int main() { Test test1(20); Test test2=Getval(test1); } Test(rhs);显示生成了临时对象rhs, Test& 不生成作返回用途的对象 只返回显式生成的临时对象的地址 又因为main函数 Test test2=Getval(test1) 对象test2 = 临时对象的地址 Getval(地址)解引用 Test test2 = * 返回的是一个地址,所以整个过程没有优化 临时对象生存周期 ;结束 return Test(rhs);结束就调用析构 而返回的却是这个已经销毁的临时对象的地址。
-
不能返回局部变量的指向或者引用
//Test test2=Getval(test1);
//Test& Getval(Test& rhs){Test tmp(rhs);return tmp;}
//调用拷贝构造后覆盖tmp的栈帧class Test { public: Test(int a=10):ma(a) { cout<<"Test::Test(int)"<<endl; } Test(const Test& rhs):ma(20) { cout<<"Test::Test(Test)"<<endl; } //const Test * const int getValue()const { return ma; } void show() { getValue(); cout<<"ma"<<ma<<endl; } ~Test() { cout<<"Test::~Test()"<<endl; } private: int ma; }; Test& Getval(Test& rhs) { Test tmp(rhs); return tmp; } int main() { Test test1(20); Test test2=Getval(test1); } 开始,实参传形参,作形参变量或者对象的初始化。 然后开辟Getval函数的函数栈帧, tmp这个对象再这个栈帧上的一个内存块 将tmp返回 即 将这个对象地址返回 函数调用完要清栈帧 tmp就要将这个内存块归还给系统,tmp就成了无效的对象 Test test2=Getval(test1); 要调用拷贝构造函数生成test2,就会由栈帧的开辟, 就会覆盖tmp的栈帧,值就会发生变化出错
函数指针
typedef int(*FUNC)(int,int);
int sum(int a,int b)
{
return a+b;
}
int main()
{
FUNC fun=∑
int n=*fun(10,20);
}
.*操作符
class Test
{
public:
Test(int a):ma(a)
{
}
void show()
{
cout<<ma<<endl;
}
private:
int ma;
};
typedef void(Test::*func)();
int main()
{
Test t1(10);
func =&Test::show;
(t1.*func)();
Test t2=new Test(20);
(t2->*func)();
}
->*操作符
class Test
{
public:
Test(int a):ma(a)
{
}
void show()
{
cout<<ma<<endl;
}
private:
int ma;
};
typedef void(Test::*func)();
int main()
{
Test t2=new Test(20);
(t2->*func)();
}