Class with pointer member(s)

本文详细介绍了C++中类包含指针时,如何处理拷贝构造函数和拷贝赋值操作以防止内存泄漏。通过实例展示了默认拷贝构造和赋值操作可能导致的问题,并给出了正确的实现方式,包括自我赋值检测。同时,解释了new和delete的使用规则,以及堆栈、堆和全局对象的生命周期。强调了array new与array delete的匹配使用重要性。
摘要由CSDN通过智能技术生成

class里带有指针,一定要关注:

  1. 拷贝构造函数
  2. 拷贝赋值函数
  3. 析构函数
    实现带有指针的类,一定要重新实现拷贝构造和拷贝赋值函数!如果使用默认拷贝就会有内存泄漏的风险。
String a("hello");
String b("world");
b = a;   // 使用默认拷贝就会内存泄漏,b不再指向原先内存

ctor 和 dtor

inline String::String(const char* cstr) {
   if (cstr) {   // 如果指定了初值
      m_data = new char[strlen(cstr)+1];
      strcpy_s(m_data, strlen(cstr) + 1, cstr);  // 这里要使用strcpy_s, strcpy有安全风险
   }
   else {   // 未指定初值
      m_data = new char[1];
      *m_data = '\0';
   }
}

inline String::~String(){
   delete[] m_data;    // 清理内存,释放动态分配的内存
}

copy ctor

inline String::String(const String& str) {
   m_data = new char[ strlen(str.m_data) + 1 ];
   strcpy_s(m_data, strlen(str.m_data) + 1, str.m_data);
}
{
	String s1("hello");
	String s2(s1);  // 直接取另一个object的private data, (兄弟之间互为友元)
}

copy op=

inline String& String::operator=(const String& str) {
   if (this == &str)   // self assignment检测自我赋值
      return *this;
   delete[] m_data;  // 释放内存
   m_data = new char[ strlen(str.m_data) + 1 ];  // 分配内存
   strcpy_s(m_data, strlen(str.m_data) + 1, str.m_data);  // 赋值数据
   return *this;   // this指针就是指向调用者本身
}

上面代码中的检测自我赋值部分一定不能省略,非常重要! 如果两个指针指向同一块内存,operator= 第一步就是delete, 就会造成指针访问不存在的内存,产生不确定行为。

new 和 delete

stack, heap, global对象的生命周期

stack中的对象会自动调用dtor, 不需要手动delete;
new动态分配的是heap内存;new得的内存就有责任delete掉,释放内存。

new:先分配内存,再调用ctor

delete: 先调用dtor,再释放内存

array new 一定要搭配array delete

比较下面两种delete方式的差别

	String *p = new String[3];
	// 1 delete p;
	// 2 delete[] p;

方式1是不正确的用法,只唤起1次dtor,会造成内存泄漏;
方式2在delete后面加上[]相当于告诉编译器删除的是array
new [] 搭配 delete[]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值