函数返回对象有两种常见的方式
1.重载拷贝构造函数和赋值函数
见下面的fun1
2.重载赋值函数,然后用"return <构造函数>"的格式
见下面的fun2
测试代码.对类C重载了赋值运算,构造,析构,拷贝构造.然后写了两个函数来测试返回值
class C
{
public:
int i;
C &operator = (C &o) //赋值
{
i = o.i;
cout<<"C &operator = (C &o) "<<i<<endl;
return *this;
};
C(int p) //构造
{
i = p;
cout<<"C() "<<i<<endl;
};
~C() //析构
{
cout<<"~C() "<<i<<endl;
};
C(C &o) //拷贝构造
{
i = o.i*10;
cout<<"C(C &o) "<<i<<endl;
};
};
C fun1()
{
return C(1);
}
C fun2()
{
C o(2);
return o;
}
void main()
{
C o(3);
cout<<"---fun1---"<<endl;
o = fun1();
cout<<"---fun2---"<<endl;
o = fun2();
cout<<"---main---\no.i = "<<o.i<<endl;
system("PAUSE");
}
{
public:
int i;
C &operator = (C &o) //赋值
{
i = o.i;
cout<<"C &operator = (C &o) "<<i<<endl;
return *this;
};
C(int p) //构造
{
i = p;
cout<<"C() "<<i<<endl;
};
~C() //析构
{
cout<<"~C() "<<i<<endl;
};
C(C &o) //拷贝构造
{
i = o.i*10;
cout<<"C(C &o) "<<i<<endl;
};
};
C fun1()
{
return C(1);
}
C fun2()
{
C o(2);
return o;
}
void main()
{
C o(3);
cout<<"---fun1---"<<endl;
o = fun1();
cout<<"---fun2---"<<endl;
o = fun2();
cout<<"---main---\no.i = "<<o.i<<endl;
system("PAUSE");
}
运行结果
C() 3
---fun1---
C() 1
C &operator = (C &o) 1
~C() 1
---fun2---
C() 2
C(C &o) 20
~C() 2
C &operator = (C &o) 20
~C() 20
---main---
o.i = 20
请按任意键继续. . .
---fun1---
C() 1
C &operator = (C &o) 1
~C() 1
---fun2---
C() 2
C(C &o) 20
~C() 2
C &operator = (C &o) 20
~C() 20
---main---
o.i = 20
请按任意键继续. . .
可见.fun1内共生成了一个临时对象.函数调用顺序是
return用的临时对象的构造->赋值运算传值->临时对象的析构
fun2内共生成了两个临时对象.效率较低,但便于修改.函数调用顺序是
fun2内局部对象的构造->return用的临时变量的拷贝构造->局部对象的析构->赋值运算传值->临时对象的析构
fun2的效率较低,但便于修改;fun1又要有构造函数的支持才行
如果返回引用的话,就没有这么多临时变量了.但是返回值为某一类型的引用一般是为了实现链式表达.而且有下面几点要注意:
1.不能返回局部变量的引用.因为在外面的对象接到这个引用之前就已经被析构掉了.它只能接到一个空对象
2.不要返回函数内部new分配的内存的引用.因为delete的安排会变得麻烦,而且很容易造成内存泄漏或访问到已经delete的对象
3.可以返回类成员的引用,但最好是const
4.不要返回静态变量的引用.比如,operator+返回了静态变量的引用.((a+b) == (c+d))会永远为true而导致错误
详细的可以参考这里.好像是Effective C++里面的内容吧
其实我就经常不返回对象而是返回new得到的对象的指针.管理起来相当麻烦...也许这是一种坏习惯吧,改改好了
又被蚊子咬了..郁闷.