简单谈谈C++中的函数形参与浅拷贝
标签 : c++ examples
[TOC]
最近要考C++,复习过程中遇到一些问题,总结记录一下。文中代码均在中运行的
字面上都知道,函数传递参数有值传递和引用传递,但具体区别是什么呢?除了一个传对象拷贝,一个传对象本身之外,还有哪些影响?
这里定义一个str
类,只有一个private char*st
变量;有几个基本的函数,重载了=
和==
运算符,str & operator=(str const & a)
和str & operator==(str a)
,用于用不同方式实现赋值代码如下:
代码
#include#include using namespace std; class str {private: char *st; public: str(char *a) { set(a); cout<<"构造函数:str addr "< <<" st addr "<<&st<<" st point to "<<(void *)st<<" st "< <
- 使用
str & operator==(str a)
重载的输出:
set:before new st addr 0xbfce5374 st point to 0xb785c680set:after new st addr 0xbfce5374 st point to 0x9bffa10构造函数:str addr 0xbfce5374 st addr 0xbfce5374 st point to 0x9bffa10 st heset:before new st addr 0xbfce5378 st point to 0x804abc4set:after new st addr 0xbfce5378 st point to 0x9bffa20构造函数:str addr 0xbfce5378 st addr 0xbfce5378 st point to 0x9bffa20 st sheshow func: heshow func: sheop:形参 str a addr 0xbfce537c a.st addr 0xbfce537c a.st point to 0x9bffa10 a.st content heset:before new st addr 0xbfce5378 st point to 0x9bffa20set:after new st addr 0xbfce5378 st point to 0x9bffa20~str:before str addr 0xbfce537c st addr 0xbfce537c st point to 0x9bffa10 st content heshow func: show func: he~str:before str addr 0xbfce5378 st addr 0xbfce5378 st point to 0x9bffa20 st content he~str:before str addr 0xbfce5374 st addr 0xbfce5374 st point to 0x9bffa10 st content
注意第二次两行show
之前的那句~str:before str addr 0xbfce537c st addr 0xbfce537c st point to 0x9bffa10 st content he
- 使用
str & operator=(str const & a)
重载,将main
中s2==s1;
注释掉,使用s2=s1;
, 输出:
set:before new st addr 0xbff47b38 st point to 0x804aba0set:after new st addr 0xbff47b38 st point to 0x9693a10构造函数:str addr 0xbff47b38 st addr 0xbff47b38 st point to 0x9693a10 st heset:before new st addr 0xbff47b3c st point to 0x8049302set:after new st addr 0xbff47b3c st point to 0x9693a20构造函数:str addr 0xbff47b3c st addr 0xbff47b3c st point to 0x9693a20 st sheshow func: heshow func: sheop:形参 str const & a addr 0xbff47b38 a.st addr 0xbff47b38 a.st point to 0x9693a10 a.st content heset:before new st addr 0xbff47b3c st point to 0x9693a20set:after new st addr 0xbff47b3c st point to 0x9693a20show func: heshow func: he~str:before str addr 0xbff47b3c st addr 0xbff47b3c st point to 0x9693a20 st content he~str:before str addr 0xbff47b38 st addr 0xbff47b38 st point to 0x9693a10 st content he
分析
- 使用
str & operator==(str a)
重载时,s1的地址为0xbfce5374
,a的地址为0xbfce537c
,确实是另外创建了新变量a,但是,两者的st均指向同一个地址0x9bffa10
- 使用
str & operator=(str const & a)
重载时,s1和a的地址均为0xbff47b38
- 两次输出的区别在于使用值传递时,即第一个输出结果多了一句输出:
~str:before str addr 0xbfce537c st addr 0xbfce537c st point to 0x9bffa10 st content he
可以看出,主要区别在于,参数类型不是引用时,形参为值传递,默认的复制构造函数就是简单的把成员变量依次赋值,所以str a
的st和s1
的st指向的同一段内存,函数str & operator==(str a)
执行完,自动变量a会销毁,调用析构函数,释放st所指向的内存并设指针为空,所以为null。而使用函数str & operator=(str const & a)
,则不会代用析构函数。由于这里未对变量a做修改,所以去掉const不影响,不过最好保留。
关于拷贝
- 对象间赋值(=)是一个拷贝过程
- 浅拷贝
- 实现对象间数据元素的一一对应复制。
- 深拷贝
- 当被复制的对象数据成员是指针类型时,不是复制该指针成员本身,而是将指针所指的对象进行复制。 系统提供的拷贝(如默认拷贝构造函数等)只能实现浅拷贝,深拷贝必须自定义
作者更多文章: | |