【C++】拷贝构造函数与赋值操作符的本质性区别分析
来源:互联网 发布:公司大数据 编辑:程序博客网 时间:2024/06/08 06:32
在C++中,牵扯到两个对象相互初始化,赋值,经常会调用拷贝构造函数和赋值操作符,许多新手也经常在此迷惑,究竟何时调用拷贝构造函数,何时调用赋值操作符呢?
在语法层面上来说,当你需要用一个已经存在的对象来初始化一个之前未曾存在的对象时候,会调用拷贝构造函数,当两个对象都已经存在,将两者用=操作符作为参数调用时候,会调用赋值操作符,可是两者究竟有什么本质区别呢?
首先需要明白构造函数的功能,以及背后究竟背着我们做了些什么工作。
大家在看完书的时候,肯定会得出一个结论,就是用来初始化一个对象,就是包括了分配内存及初始化成员变量的功能,这个的确有这么一个功能,然而这里得从两个方面来讨论对象的初始化,在栈上分配和从堆上分配。
1.从栈上分配
从栈上分配,定义一个类对象,构造函数究竟是怎么工作的,什么时候分配内存,什么时候初始化成员变量?其实从函数的工作原理上来讲,已经不存在分配内存这一说法,在这个函数被调用前,esp就会被调整,预留一段函数帧来供栈上变量使用,栈上变量的标识符也引用了特定的栈上内存,当函数结束时候,会恢复现场,调整esp,那么该段内存被释放,也就是自动变量自动释放的原理。由此我们可以得出,构造函数并不存在分配内存这一说法,不过也可以称之为供编译器调整函数帧的功能。假如在不存在虚函数的情况下,构造函数仅仅用于初始化成员变量,而当存在虚函数的情况下,那么构造函数的另一个重要的功能就是写入虚表。
当类中存在虚函数的情况下,每个类都会对应一个虚表,虚表依次存放着类中声明的虚函数,并由构造函数写入到对象所占内存的头部,这是为了更好的实现继承及父子强制转换和多继承的用途。所以无论是什么构造函数,拷贝构造也好,普通的也好,一个重要的功能就是写入虚表指针并执行剩下的初始化语句。当然,在类中不存在虚函数的情况下,行为和赋值操作符没有什么不同。
2.从堆上分配
从堆上分配的行为和栈上差不多,就是分配内存的一步由new操作符分配并负责调用构造函数,构造函数依据传入的this指针来进行剩下的工作。
所以在从实现来讲,拷贝构造函数和赋值操作符的最大一个区别就是拷贝构造函数会覆盖未初始化类内存区的虚表,而赋值操作符仅仅执行函数体内内容,不会覆盖虚表。
- 【C++】拷贝构造函数与赋值操作符的本质性区别分析
- 拷贝构造函数与重载赋值操作符的区别
- 拷贝构造函数和赋值操作符的区别
- 拷贝构造函数和赋值操作符的区别 .
- 拷贝构造函数与赋值操作符
- 拷贝构造函数与赋值操作符的具体实现
- 重载赋值运算符与拷贝构造函数的区别
- 拷贝构造函数与赋值运算符重载的区别
- 拷贝构造函数与赋值运算符的区别
- 拷贝构造函数与赋值运算符重载的区别
- 重载赋值运算符与拷贝构造函数的区别
- 重载赋值运算符与拷贝构造函数的区别
- 拷贝构造函数与赋值运算符重载的区别
- 拷贝构造函数与赋值构造函数的区别
- 拷贝构造函数与赋值构造函数的区别
- 构造函数,复制构造函数与拷贝赋值操作符
- 拷贝构造函数与拷贝赋值操作符
- C++中拷贝构造函数与拷贝赋值操作符
- windows后台服务程序范例
- awk正则匹配列中指定的字符
- java 计算PMT公式
- Oracle to_date
- POJ 1836(双向LIS)
- 【C++】拷贝构造函数与赋值操作符的本质性区别分析
- 使用CASE WHEN进行字符串替换处理
- windows下搭建cocos2dx Android开发环境
- 画椭圆 - HTML5 Canvas 作图
- 拷贝构造函数的疑问
- 设计模式之简单工厂模式
- WSAEventSelect
- jquery中ajax方法使用json需注意的小问题
- QTP录制过程中关于浏览器设定的问题