拷贝构造函数之深拷贝浅拷贝
来源:互联网 发布:单片机相序检测程序 编辑:程序博客网 时间:2024/05/29 08:30
何为拷贝构造函数?
一般一个构造函数的参数是自身类类型的const引用,则这个构造函数就是拷贝构造函数。
拷贝构造函数是被用来初始化 非引用类 类型参数, 参数必须是引用类型。
如:
class MyString
{
public:
MyString( const MyString& Mystr); //拷贝构造函数
};
如果我们没有自己定义拷贝构造函数,编译器就会自动会定义一个合成拷贝构造函数。
/********************************************************************************************************/
说到拷贝构造函数,得扯扯构造函数。
1、构造函数的作用就一点: 初始化!!!分配内存不是构造函数管得到的事情。
malloc/free就仅仅是分配内存;
而new/delete分配内存,如果存在构造函数就会调用构造函数。如:内置类型,int double 等并没有构造函数new操作就没有初始化这一步,而像string 类类型等就会调用构造函数初始化。
2、编译器在需要构造函数时才会合成构造函数;初始化时,如果有对应的构造函数,编译器就会帮你调用之。编译器只会帮你到这。。。
/********************************************************************************************************/
回到正题:
如果我们没有自定义copy constructor,编译器就会合成拷贝构造函数,然而这个copy constructor是位拷贝实现的,这是很危险的,我做了一些实验做以验证。
先来说说深拷贝浅拷贝:
浅拷贝就是位拷贝,意思是按地址进行拷贝,深拷贝就是值拷贝,拷贝的是内容。可这样理解:如果一个类拥有资源(堆等),当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。
浅拷贝时,两个类对象同时指向同一块内存地址,当一个对象被delete时,对应的内存位置会被释放,这时另一个对象的内存指针就变成了野指针,这很危险。这时就应该编写operator=和copy constructor来实现值拷贝。
代码如下:
/*拷贝构造函数*/
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
class MyString
{
friend class ShowMyString;//友元类
public:
MyString(string s, int l, char* p) //有参构造
{
S = s;
length = l;
if (p == NULL)
{
P = new char[1];
p[0] = '\0';
}
else
{
P = new char[length + 1];
strcpy(P, p);
}
}
MyString(const MyString& mys)//拷贝构造函数 深拷贝
{
S = mys.S;
length = mys.length;
//P = new char[length + 1];//深拷贝(拷贝一个非引用类类型,重新分配资源)若是深拷贝 指针pstr安全,输出hhhh.
//if (P != 0)
//{
// strcpy(P, mys.P);
// P[length] = '\0';
//}
P = mys.P;//直接指针赋值导致浅拷贝
}
~MyString()
{
if (P != NULL)
{
delete[] P;
}
}
void showstr()
{
cout << "C++风格的字符串:" << S << endl << "C风格的字符串:" <<P << endl;
}
private:
string S;
char* P;
int length;
};
class ShowMyString
{
public:
void show(MyString& ms);
};
void ShowMyString::show(MyString& ms)
{
cout <<"C++风格的字符串:" << ms.S <<endl<< "C风格的字符串:" << ms.P << endl;
}
int main()
{
MyString * pstr = NULL;
{
MyString s("hello", 4, "hhhh");
ShowMyString sh;
sh.show(s);
pstr = new MyString(s);
} //对象s被delete,此时指针pstr为野指针,输出乱码了
pstr->showstr();
cout << endl;
////////////////////////////////
/*MyString s1 = s;
sh.show(s1);*/
system("pause");
return 0;
}
浅拷贝的结果:
深拷贝的结果:
- 拷贝构造函数 深拷贝 浅拷贝
- 拷贝构造函数(深拷贝,浅拷贝)
- 拷贝构造函数浅拷贝深拷贝
- 拷贝构造函数,浅拷贝,深拷贝
- 拷贝构造函数 深拷贝 浅拷贝
- 拷贝构造函数----深拷贝、浅拷贝
- C++拷贝构造函数之深拷贝、浅拷贝
- C++学习之拷贝构造函数(深拷贝,浅拷贝)
- 拷贝构造函数之深拷贝浅拷贝
- 拷贝构造函数与赋值函数;深拷贝,浅拷贝
- 深拷贝、浅拷贝构造函数问题
- 深拷贝、浅拷贝构造函数
- 复制构造函数&深拷贝&浅拷贝
- C++构造函数之深拷贝与浅拷贝
- C++构造函数之浅拷贝和深拷贝
- 默认拷贝构造函数,浅拷贝,深拷贝
- C++拷贝构造函数(深拷贝,浅拷贝)
- C++拷贝构造函数(深拷贝,浅拷贝)
- 第五周项目一 三角形
- 面向对象编程学习一点感悟(java)
- 俄罗斯方块单人游戏设计概述
- git 提交模版设置
- Settings->Accessibility->Large text分析
- 拷贝构造函数之深拷贝浅拷贝
- Java学习·final
- 动态规划 —— 求解二项式系数
- POJ 3904 Sky Code (容斥原理)
- 第五周项目一 2
- sql 常用数学函数
- 清除浮动
- 关于垃圾回收的小结
- JBPM4关于Assignee动态获取------OA系统工作流环节问题