返回值是对象
1. 唯一(?)安全的做法是要将返回值存放在一个register中,因为放在stack和全局都不安全。
2. 对象所占用的空间是不能保存在一个register中的。
所以现在的做法是,在函数参数中传入一个对象的指针,将对象的值存放在这个地方,最后返回的时候返回这个指针。
输入参数是对象
那么就会调用拷贝构造函数,如果没有拷贝构造函数,就会使用默认的拷贝。
我们来看一个例子,看看拷贝构造函数是怎么被调用的。
#include <iostream>
#include <string>
using namespace std;
class HowMany2 {
string name; // Object identifier
static int objectCount;
public:
HowMany2(const string& id = "") : name(id) {
++objectCount;
print("HowMany2()");
}
~HowMany2() {
--objectCount;
print("~HowMany2()");
}
// The copy-constructor:
HowMany2(const HowMany2& h) : name(h.name) {
name += " copy";
++objectCount;
print("HowMany2(const HowMany2&)");
}
void print(const string& msg = "") const {
if(msg.size() != 0)
cout << msg << endl;
cout << '/t' << name << ": "
<< "objectCount = "
<< objectCount << endl;
}
};
int HowMany2::objectCount = 0;
// Pass and return BY VALUE:
HowMany2 f(HowMany2 x) {
x.print("x argument inside f()");
cout << "Returning from f()" << endl;
return x;
}
int main() {
HowMany2 h("h");
cout << "Entering f()" << endl;
HowMany2 h2 = f(h);
h2.print("h2 after call to f()");
cout << "Call f(), no return value" << endl;
f(h);
cout << "After call to f()" << endl;
} ///:~
这个程序的output是
HowMany2()
h: objectCount = 1
Entering f()
HowMany2(const HowMany2&) 可以看到,在执行函数f()之前,就先拷贝构造了h。
h copy: objectCount = 2
x argument inside f()
h copy: objectCount = 2
Returning from f()
HowMany2(const HowMany2&) 函数返回之前,因为返回的是对象,所以又调用了拷贝构造。
h copy copy: objectCount = 3
~HowMany2() 之前构造的对象,没有用了,被销毁
h copy: objectCount = 2
h2 after call to f()
h copy copy: objectCount = 2
Call f(), no return value 下面这个是调用了f(),但是没有返回值的情况
HowMany2(const HowMany2&) 作为参数的拷贝构造
h copy: objectCount = 3
x argument inside f()
h copy: objectCount = 3
Returning from f()
HowMany2(const HowMany2&) 作为返回值的拷贝构造
h copy copy: objectCount = 4
~HowMany2() 但是这个返回值因为没人用,所以马上就销毁了
h copy copy: objectCount = 3
~HowMany2()
h copy: objectCount = 2
After call to f()
~HowMany2()
h copy copy: objectCount = 1
~HowMany2()
h: objectCount = 0