析构函数、复制构造函数,operator=以及深拷贝浅拷贝问题
来源:互联网 发布:plc和单片机哪个工资高 编辑:程序博客网 时间:2024/06/08 07:10
在C++中,伴随类的有三个已经写好的特殊函数,它们是析构函数、复制构造函数和operator=。在许多情况下,都可以采用编译器提供的默认操作,有些时候却不行。
1,析构函数
析构函数是每个类中必要的函数,一般不需要单独定义,在类形成的时候会自动定义。当一个对象超出其作用域或者执行delete时,就调用析构函数。通常,析构函数的作用是释放使用对象时占用的所有资源,这其中包括每一个相应的new调用delete,以及关闭所有打开的文件等。默认操作是对每一个成员变量都使用析构函数。析构函数的固定形式是~ClassName();。
2,复制构造函数
在我们定义类的对象的时候,一般都会用到复制构造函数,复制构造函数一般可以通过下面三种方式调用(例如Test对象):
- 声明的时候初始化,例如 Test B = A; Test B( A ); 而不是 B = A;。
- 使用按值调用传递(而不是通过&或constant &)的对象无论如何都应该减少使用。
- 通过值(而不是通过&或const &)返回对象。
默认情况下,复制构造函数操作的对象是类中每一个成员变量,简单数据类型(int、char或指针 )的变量,直接赋值就好,对于本身又是类对象的数据成员,它本身的复制构造函数又会作用于其每一个数据成员。
3,operator=
当=作用于两个已经构造的函数时,调用复制赋值运算符operator=。它的默认情况跟复制构造函数一样,也是作用于每一个数据成员。
4,浅拷贝( shallow copy),深拷贝(deep copy)
一般情况下,类的数据成员是由基本数据类型(int、double、vector<int>、string甚至是vector<string>)构成时三大函数的默认值都是适用的,但当类中存在数据成员是指针,而且这个指针指向一个动态分配地址的对象时,,默认的析构函数不会对指针进行任何操作(一个很好的理由就是释放这个指针就必须删除自身)。而且,复制构造函数和operator=都不复制指针指向的对象,而是简单的复制指针的值,这样的话,就会导致所有的指针都指向同一个对象,这被称为浅拷贝,而我们一般期望的是深拷贝。
下面代码展示了一个浅拷贝的示例:
#include <iostream>using namespace std;class Test{public: explicit Test(int initValue = 0) { storedValue = new int (initValue); } int read() const { return *storedValue; } void write(int x) { *storedValue = x; }private: int * storedValue; //数据成员是指针,默认值不能用};int main(){ Test a(2); Test b = a; Test c; c = b; a.write(3); cout << a.read() << endl << b.read() << endl << c.read() << endl; return 0;}上述代码逻辑上只有a为3,但实际上输出了3个3,问题就在于默认的operator=和复制构造函数都只是复制指针storedValue,导致三个对象的指针storedValue均指向了同一个int型变量,这些复制都是浅复制。下述代码通过三大函数来解决这个问题。
#include <iostream>using namespace std;class Test{public: explicit Test( int initValue = 0 ); Test( const Test & rhs ); //复制拷贝函数 ~Test(); //析构函数 const Test & operator = ( const Test & rhs ); //operator= int read(); void write( int x );private: int * storedValue; //数据成员是指针,默认值不能用};Test::Test(int initValue){ storedValue = new int( initValue );}Test::Test( const Test & rhs){ storedValue = new int( *rhs.storedValue );}Test::~Test(){ delete storedValue;}const Test & Test::operator=( const Test & rhs){ if( this != &rhs) //判断 = 两侧是否是同一对象 *storedValue = *rhs.storedValue; return *this;}int Test::read(){ return *storedValue;}void Test::write(int x){ *storedValue = x;}int main(){ Test a(2); Test b = a; Test c; c = b; a.write(3); cout << a.read() << endl << b.read() << endl << c.read() << endl; return 0;}上面的输出结果是3,2,2。三个对象均有独立的变量空间,而不是上面的三个指针指向同一个变量。所以,当一个类的数据成员为指针并且深拷贝很重要的时候,一般的做法就是自己实现三大函数,
阅读全文
0 0
- 析构函数、复制构造函数,operator=以及深拷贝浅拷贝问题
- 复制构造函数&深拷贝&浅拷贝
- 拷贝构造函数, operator =
- 深拷贝、浅拷贝构造函数问题
- 浅拷贝、深拷贝以及拷贝构造函数
- C++拷贝构造函数深入分析以及重写operator =
- C++拷贝构造函数深入分析以及重写operator =
- 拷贝构造函数以及复制函数
- C++拷贝构造函数(包括默认拷贝构造函数以及深拷贝、浅拷贝)
- 十、构造函数和析构函数(四) 拷贝构造函数、默认拷贝构造函数、拷贝构造函数调用几种情况、深拷贝浅拷贝、构造函数和=操作符区别、禁止对象拷贝
- 拷贝构造函数 深拷贝 浅拷贝
- 拷贝构造函数(深拷贝,浅拷贝)
- 拷贝构造函数浅拷贝深拷贝
- 拷贝构造函数,浅拷贝,深拷贝
- 拷贝构造函数 深拷贝 浅拷贝
- 拷贝构造函数----深拷贝、浅拷贝
- C++拷贝构造函数和operator=
- 拷贝构造函数与重载operator =
- 内存泄漏小结
- HBuilder快捷键
- js中常用方法-去除字符串空格,各类型验证,获取url参数等
- JavaScript实现四则运算器程序
- Linux 文件及其操作
- 析构函数、复制构造函数,operator=以及深拷贝浅拷贝问题
- Java 5种创建对象的方式
- 如何设置xampp的phpmyadmin外网访问?
- Lombok:让JAVA代码更优雅
- 户外决策带你上王者
- mongo教程-基础操作命令篇
- php-人员权限管理(RBAC)
- Leetcode 513 Find Bottom Left Tree Value
- redis安装配置jedis客户端访问redis相关问题总结