C++浅拷贝 深拷贝 计数器 写时拷贝技术

1浅拷贝

1.1C++自己提供的两个拷贝控制函数

class String{
public:
        String(const char* str = NULL);
        //拷贝构造函数
        String(const String& str);
       //拷贝赋值运算符重载
        String& operator=(const String& str);
        ~String();
private:
        char* data;
};

1.2概念

只拷贝指针地址。通常默认拷贝构造函数与赋值运算符重载都是浅拷贝

2深拷贝

2.1概念

重现分配堆内存,拷贝指针指向内容
例如

#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
class Student{
private:
	char *name;
	bool sex;
	int age;
public:
	//const char *是字符串类型
	Student(const char *name,int sex,int age):sex(sex),age(age){	
	cout<<"construct :"<<this<<endl;
	if(NULL ==name){//判空处理理 如果姓名为空传进来的花  当析构时  释放空指针会吐核;
		this->name=new char[1];
		this->name[0]='\0';
	}else{	
		this->name=new char[(strlen(name)+1)];
		strcpy(this->name,name);
	}
}
	//深copy   
	Student(const Student& s){
		sex=s.sex;
		age=s.age;
		this->name=new char[(strlen(s.name)+1)];
		strcpy(this->name,s.name);

	}
	Student& operator=(const Student &s){
	if(this!=&s){//检查是否自身赋值
		sex=s.sex;
		age=s.age;
		delete []name;//先释放子前的动态内存,避免内存泻露
		name=new char[(strlen(s.name)+1)];
		strcpy(this->name,s.name);
		}
		return *this;
	}
	~Student(){
		delete [] this->name;
	}
};
void Func1(Student s){

}
Student func2(){
	Student s("lvke",true,21);
	return s;
}

int main(){
	Student s1("lvke1",true,21);
	Student s2=s1;
	Student s3("lvke3",true,21);
	s3=s1;
}

2.2比较

在这里插入图片描述

优点 缺点
浅拷贝 浅拷贝 只有一份数据,节省空间 因为多个指针指向同一个空间,容易引发同一内存多次释放的问题。
深拷贝 每个指针指向不同地址,没有同一内存多次释放的问题 存在多份相同数据,浪费空间。

3计数器技术

数据相同共享一份内存 计数器技术就是兼有浅拷贝与深拷贝优点的一种技术。

3.1实现

1:在指针中加入一个计数器
2:如果每次拷贝 计数器加1
3:析构时减1 只有当count=1时 才会析构数据内存

#include<iostream>
#include<cstring>
using namespace std;
struct Data{
	int count;
	char* str;

};
class String{
public:
	String(const char* str=NULL){
		//第一次构造
		data=new Data;
		data->count=1;
		data->str=new char[strlen(str)+1];
		strcpy(data->str,str);
	}
	String(const String& str){
			//拷贝构造函数
			data=str.data;
			data->count++;
	}
	String& operator=(const String& str){
		//赋值运算符重载
		if(&str!=this){
			data=str.data;
			data->count++;
		}
		return *this;

	}
	~String(){
		--data->count;
		if(0==data->count){
			delete [] data->str;
			delete data;
			data=NULL;
		}		
	}
	friend ostream& operator<<(ostream& os,String const& str){
		os<<str.data->str;
		return os;
	}
private:
	Data* data;
};
int main(){
	String s("hello world");
	cout<<s<<endl;
}

4写时拷贝技术

以上都是拷贝复制操作,如果字符串发生改变,那么才是真正的写时拷贝。
例如:实现+=操作

String& String::operator+=(const String& str){
        base.count--;
        // 一些具体操作...
        base = new StringBase();
        base.count++; 
        return *this;
}
发布了27 篇原创文章 · 获赞 4 · 访问量 1337

猜你喜欢

转载自blog.csdn.net/weixin_45639955/article/details/104308278