由于使用c++太少,在项目中定义成员函数时,想着应该返回vector<string>&还是vector<string>;思考上升到函数返回对象时,经历几次构造函数。
依稀记得函数返回对象,需要经过生成一个临时对象(call copy constructor),然后根据语句是变量声明还是复制分别调用copy constructor 或者assign operator;
分别使用g++(4.84.xx)和VS2010+实验以下code:
1 #include "stdafx.h" 2 #include <stdlib.h> 3 #include <vector> 4 #include <iostream> 5 using namespace std; 6 class A { 7 public: 8 int a; 9 A() :a(10) {} 10 ~A() 11 { 12 //printf("~A(),addr=%p\n",this); 13 } 14 A(const A& inst) 15 { 16 printf("copy constructor\n"); 17 this->a = inst.a; 18 } 19 A& operator =(const A& inst) 20 { 21 printf("operator =\n"); 22 this->a = inst.a; 23 return *this; 24 } 25 int& getA() 26 { 27 return a; 28 } 29 }; 30 A func() 31 { 32 A a; 33 a.a = 3; 34 printf("func() a.a addr=0x%p\n", &a.a); 35 return a; 36 } 37 int main() 38 { 39 printf("test A a = func()\n"); 40 A a = func(); 41 A a1 = func(); 42 printf("a.a,a1.a addr=0x%p, 0x%p\n", &a.a, &a1.a); 43 //A& b = func();//intial value of reference to non-const must be a lvalue 44 int& c = a.getA(); 45 a.a = 100; 46 printf("%d\n",c); 47 A* b = new A(); 48 int& c1 = b->getA(); 49 b->a = 100; 50 printf("delete before %d\n", c1); 51 delete b; 52 printf("delete after %d\n", c1); 53 system("pause"); 54 return 0; 55 }
1、结果发现,在release版本(准确的说法是打开了优化项),A a = func();这种形式被编译器优化,不会调用copy constructor,即使a=func()也只有一次assign operator(不管是否打开优化选项);
禁止优化项,得到的结果,A a = func();调用一次copy constructor。
2、另外考虑一个对象的成员函数什么时候应该使用引用返回成员变量呢?
百度搜索,找不到想要的解答;自己思考,引用返回成员变量,会导致它的作用域发生变化,如果对象被释放,可能引起资源被释放还在使用的问题(例如野指针);
因此,我觉得可以使用引用返回例如vector<string>的对象,但开发者应该注意调用者和被调用者之间的依赖关系;另外在提供对外api时,如果使用引用对象返回的形式,一定需要注明该对象的生命周期。
期望有大神可以对这个问题提出经验之谈,本人实在缺乏经验。
以下是打开优化时,VS2017的输出结果(gcc的%p会自动加上0x):
test A a = func()
func() a.a addr=0x0034FAD4
func() a.a addr=0x0034FAD0
a.a,a1.a addr=0x0034FAD4, 0x0034FAD0
100
delete before 100
delete after 7171672