
正文
C++中的浅拷贝和深拷贝
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
浅拷贝(shallow copy)与深拷贝(deep copy)对于值拷贝的处理相同,都是创建新对象,但对于引用拷贝的处理不同,深拷贝将会重新创建新对象,返回新对象的引用字。浅拷贝不会创建新引用类型。
怎么判断一个类的赋值构造函数的方法:根据类的实现
1。如果它有一个用原生指针指针实现的对象引用,或是用boost::shared_ptr等引用分享所有权的智能指针实现的对象引用,则这个拷贝是浅拷贝
2。如果是用copy_ptr这种实现了深拷贝的智能指针实现的对象引用,就是深拷贝了。copy_ptr在内部保留一个指针,当它自己解析时,它同时也销毁它在内部保存的这个指针。
最能体现深层拷贝与浅层拷贝的,就是‘=’的重载。我们以此为例。
例1:浅拷贝
class string
{
char *m_str; //对象之中含有指针数据类型
public:
string(char *s)
{
m_str=s;
}
string(){};
string&operator=(const string s)
{
m_str=s.m_str; //s1,s2指向同一个内存
return *this}
};
int main()
{
string s1("abc"),s2;
s2=s1;
cout<<s2.m_str;
}
};
例2:深拷贝
string&operator=(const string&s)
{
if(strlen(m_str)!=strlen(s.m_str))
m_str=new char[strlen(s.m_str)+]; //为被赋值对象申请了一个新的内存
if(*this!=s)
strcmp(m_str,s.m_str);
return *this;
}
浅拷贝易使对象的值发生不必要的改变。这时我们需要智能shared_ptr指针来管理。
例:
#include <vector>
using namespace std;
using namespace boost;int main (int argc, const char * argv[])
{ typedef vector< shared_ptr > sharedContainers;
sharedContainers sharedArray();
int i=;
for(sharedContainers::iterator pos = sharedArray.begin() ;pos!=sharedArray.end();++pos)
{
*pos = make_shared(++i);
}
cout<<"sharedArray[5]的初始值:"<<*sharedArray[]<<endl;
cout<<"sharedArray[5]的初始引用计数为:"<<sharedArray[].use_count()<<endl;
shared_ptr p1 = sharedArray[];
*p1 = ;
cout<<"sharedArray[5]经过赋值后的值:"<<*sharedArray[]<<endl;
cout<<"sharedArray[5]赋值后的引用计数为:"<<sharedArray[].use_count()<<endl;
shared_ptr p2(sharedArray[]);
cout<<"sharedArray[5]复制后的引用计数为:"<<sharedArray[].use_count()<<endl;
return ;
}
其输出结果为:
sharedArray[5]的初始值:6
sharedArray[5]的初始引用计数为:1
sharedArray[5]经过赋值后的值:10
sharedArray[5]赋值后的引用计数为:2
sharedArray[5]复制后的引用计数为:3
shared_ptr简单实现(主旨:引用计数reference count):
1.一个模板指针T* ptr,指向实际的对象。
2.创建类的新对象时,初始化指针并将引用计数置为1。
3.重载operator*和operator->,使得能像指针一样使用shared_ptr。
4.重载copy constructor,使其引用次数等于右操作数所指对象加一。
5.重载operator=,如果原来的shared_ptr已经有对象,则让其引用次数减一并判断引用是否为零(是否调用delete)。
然后将新的对象引用次数加一。
6.重载析构函数,使引用次数减一并判断引用是否为零(是否调用delete)。
#ifndef __SHARED_PTR_
#define __SHARED_PTR_template <typename T>
class shared_ptr {
public:
shared_ptr(T* p) : count(new int()), _ptr(p) {}
shared_ptr(shared_ptr<T>& other) : count(&(++*other.count)), _ptr(other._ptr) {}
T* operator->() { return _ptr; }
T& operator*() { return *_ptr; }
shared_ptr<T>& operator=(shared_ptr<T>& other)
{
++*other.count;
if (this->_ptr && == --*this->count)
{
delete count;
delete _ptr;
}
this->_ptr = other._ptr;
this->count = other.count;
return *this;
}
~shared_ptr()
{
if (--*count == )
{
delete count;
delete _ptr;
}
}
int getRef() { return *count; }
private:
int* count;
T* _ptr;
};#endif








