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;
}