大家好,
阅读本文章后在类的深度拷贝获得收益,下面是是章节内容
map 添加一个自定义key
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
class CDemo
{
public:
CDemo(char*str=NULL)
{
if (str==NULL)//当初始化串不存在的时候,为m_data申请一个空间存放'\0';
{
m_str=new char[1];
*m_str='\0';
}
else//当初始化串存在的时候,为m_data申请同样大小的空间存放该串;
{
int length=strlen(str);
m_str=new char[length+1];
if (m_str==NULL)
{//内存是否申请成功
cout<<"申请内存失败!"<<endl;
exit(1);
}
strcpy(m_str,str);
}
}
~CDemo()
{
if(m_str) delete[] m_str;
}
void show();
private:
char* m_str;
};
void CDemo::show()
{
cout<<m_str<<endl;
}
int main(int argc, char** argv)
{
CDemo d1="trend micro";
d1.show();
vector<CDemo> *a1=new vector<CDemo>();
a1->push_back(d1); //here
delete a1;
return 0;
}
上述代码运行时出错。
a1 -> push_back(d1); //析构一次
是在a1所指的向量的尾部插入一个CDemo对象d,d的值与d1相等(调用默认拷贝构造函数,是浅拷贝),自然d.str=d1.str,即都指向同一内存地址。
delete a1;//析构一次
会调用vector<>的析构函数~vector(),在~vector()中也一定释放了各CDemo元素的内存空间(调用每个元素的~CDemo())
,这里由于vector中只有一个元素,故只调用一次~CDemo(),
这使得d.str被释放一次。 接着,因为d1是个局部变量,在main函数退出后,d1析构函数~CDemo()被调用,而d1.str所指内存空间已经在前面被释放,
所以会出现运行时错误。
class String {
public:
String(const char* str) {
cout << "String construct" << endl;
m_data = new char[strlen(str) + 1];
strcpy(m_data, str);
}
/**
String(const String& str) {
cout << "String copy construct" << endl;
m_data = new char[strlen(str.m_data) + 1];
strcpy(m_data, str.m_data);
}**/
~String() {
cout << "String destroy" << endl;
delete[] m_data;
}
private:
char* m_data;
};
void main() {
vector<String> vec;
for (int i = 0; i < 1; i++) {
String str("hello");
vec.push_back(str);
}
cout << "end" << endl;
}
1)如果类的成员变量都是基本数据类型,浅拷贝没有任何问题;
2)如果类的成员变量包含指针或者引用,那么对这个类的对象使用时就要注意了,浅拷贝只会拷贝指针或引用本身,而不会拷贝指针或引用所指向的对象, 这样就会导致多个对象同时持有指向某个对象的指针, 容易引发在释放该对象时,出现多次释放同一对象,或者内存泄漏。
(gdb) bt
#0 0x0000003f0b02e2ed in raise () from /lib64/tls/libc.so.6
#1 0x0000003f0b02fa3e in abort () from /lib64/tls/libc.so.6
#2 0x0000003f0b062d41 in __libc_message () from /lib64/tls/libc.so.6
#3 0x0000003f0b06881e in _int_free () from /lib64/tls/libc.so.6
#4 0x0000003f0b068b66 in free () from /lib64/tls/libc.so.6
#5 0x000000342cfae19e in operator delete () from /usr/lib64/libstdc++.so.6
问题4: 右值是什么鬼?
template<typename _Tp>
inline typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t)
{
return static_cast<typename std::remove_reference<_Tp>::type&&>(__t);
}
访问速度快呀
也就是说当我们给容器中插入元素的时候容器内部实施了拷贝动作, 将我们要插入的元素再另行拷贝一份放入到容器中,
而不是将原数据元素直接放进容器中,也就说我们提供的元素必须能够被拷贝。
播种希望