合肥网站建设哪里好,什么是网络营销取得成功的基础,网站建设丶金手指下拉14,商城建设网站开发2019独角兽企业重金招聘Python工程师标准 前言 C的函数参数和返回分为按值传递和按引用传递,应用到类上面,会涉及到类的 赋值操作 复制函数 构造函数 析构函数 虽然java开发了两年,但对我而言c我还只是一个初学者.c还有很多陌生的特性需要自己亲自探索.这里用实际… 2019独角兽企业重金招聘Python工程师标准 前言 C的函数参数和返回分为按值传递和按引用传递,应用到类上面,会涉及到类的 赋值操作 复制函数 构造函数 析构函数 虽然java开发了两年,但对我而言c我还只是一个初学者.c还有很多陌生的特性需要自己亲自探索.这里用实际例子作为探索,不对之处望斧正: 由于基本类型和类在函数里的生命周期是相似的,这里以一个自定义类为例,一是为了方便观察对象的地址,二是可以了解每一步会涉及到类的哪些生命周期: 类的定义 #include iostreamusing std::cout;
using std::endl;
using std::string;class A {
public:A() {cout 构造函数: this endl;}A(const A input) {cout 复制函数: this endl;}// 复制直接返回 *this 本身A operator(const A input) {cout 赋值函数: this endl;// this 其实是个新的内存空间,啥值都没设置return *this;}~A() {cout 析构函数: this endl;}
};值传递 和 返回值 我们定义一个值传递的函数,返回的也是值 A test1(A a) {cout test1函数体:a a endl;return a;
}执行main函数如下 int main() {cout --- 对象创建 --- endl;A a;cout --- 函数调用 --- endl;A b test1(a);cout --- 结束 --- endl;return 0;
}执行结果 --- 对象创建 ---
构造函数:0x7fff5ed19768
--- 函数调用 ---
复制函数:0x7fff5ed19750
test1函数体:a0x7fff5ed19750
复制函数:0x7fff5ed19758
析构函数:0x7fff5ed19750
--- 结束 ---
析构函数:0x7fff5ed19758
析构函数:0x7fff5ed19768由此可见,在函数的栈帧里,对入参a进行了一次复制(0x7fff5ed19750),而在返回栈帧里的input时,又会对函数结果复制生成一个临时变量(0x7fff5ed19758),并回收栈帧里的input. 函数结束会把临时变量返回给b,至此结束函数调用.也就是说,这里函数的入参和返回各涉及一次复制操作 函数入参和返回使用引用 我们对test1做出修改,将入参和返回变更为引用,如下 A test1(A a) {cout test1函数体:a a endl;return a;
}将main中的b也变更为引用如下: int main() {cout --- 对象创建 --- endl;A a;cout --- 函数调用 --- endl;A b test1(a);cout --- 结束 --- endl;return 0;
}执行结果: --- 对象创建 ---
构造函数:0x7fff56dd5768
--- 函数调用 ---
test1函数体:a0x7fff56dd5768
--- 结束 ---
析构函数:0x7fff56dd5768因为是引用函数栈帧内并没有进行任何复制操作 函数返回的临时变量探索 如果函数不返回引用,或b不是引用,仍然会产生临时变量 A test1(A a) {cout test1函数体:a a endl;return a;
}
A test2(A a) {cout test2函数体:a a endl;return a;
}
int main() {cout --- 对象创建 --- endl;A a;cout --- 函数调用1 --- endl;A b1 test1(a);cout --- 函数调用2 --- endl;A b2 test2(a);cout --- 结束 --- endl;return 0;
}返回结果如下 --- 对象创建 ---
构造函数:0x7fff5daae758
--- 函数调用1 ---
test1函数体:a0x7fff5daae758
复制函数:0x7fff5daae748
--- 函数调用2 ---
test2函数体:a0x7fff5daae758
复制函数:0x7fff5daae740
--- 结束 ---
析构函数:0x7fff5daae740
析构函数:0x7fff5daae748
析构函数:0x7fff5daae758test1和test2的区别只在于返回结果是否为引用,但在栈帧外都产生了临时变量 赋值操作探索 这里再对赋值做探索,这次把以上3中情况合在一起为例,如下 A test1(A a) {cout test1函数体:a a endl;return a;
}
A test2(A a) {cout test2函数体:a a endl;return a;
}
A test3(A a) {cout test2函数体:a a endl;return a;
}
int main() {cout --- 对象创建 --- endl;A a;cout --- 函数调用1 --- endl;a test1(a);cout --- 函数调用2 --- endl;a test2(a);cout --- 函数调用3 --- endl;a test3(a);cout --- 结束 --- endl;return 0;
}输出结果 --- 对象创建 ---
构造函数:0x7fff513b6748
--- 函数调用1 ---
test1函数体:a0x7fff513b6748
赋值函数:0x7fff513b6748
--- 函数调用2 ---
复制函数:0x7fff513b6738
test2函数体:a0x7fff513b6738
赋值函数:0x7fff513b6748
析构函数:0x7fff513b6738
--- 函数调用3 ---
复制函数:0x7fff513b6728
test2函数体:a0x7fff513b6728
复制函数:0x7fff513b6730
赋值函数:0x7fff513b6748
析构函数:0x7fff513b6730
析构函数:0x7fff513b6728
--- 结束 ---
析构函数:0x7fff513b6748test1 相当于aa;除了将值赋值给自己外栈帧没有额外操作,这个很好理解test2 对入参进行复制,并把复制的入参值赋值给a并在函数栈帧结束后回收入参test3 比较复杂,会复制入参和临时变量,并把临时变量赋值给a,赋值结束后对入参和临时变量进行回收 转载于:https://my.oschina.net/tdONEmadao/blog/915677