C++面向对象高级编程(二)

目录

深浅拷贝:

拷贝赋值函数

栈和堆

探究new操作:1、分配内存 2、转型 3、构造函数

探究delete:1、调用析构函数,delete m_data  2、释放内存

探索创建对象的内存分配情况

String类


深浅拷贝:

浅拷贝:a = b;容易导致内存泄漏

深拷贝:

拷贝赋值函数

如果没有自我赋值检测,那么自身对象的m_data将被释放,m_data指向的内容将不存在,所以该拷贝会出问题。

栈和堆

探究new操作:1、分配内存 2、转型 3、构造函数

探究delete:1、调用析构函数,delete m_data  2、释放内存

探索创建对象的内存分配情况

这里以两个类做出说明:

class complex
{
	public:
		complex (double r = 0, double i = 0)
		: re (r), im (i)
		{ }
		complex& operator += (const complex&);
		double real () const { return re; }
		double imag () const { return im; }
	private:
		double re, im;
		friend complex& __doapl (complex*,
		const complex&);
};


class String
{
	public:
		String(const char* cstr = 0);
		String(const String& str);
		String& operator=(const String& str);
		~String();
		char* get_c_str() const { return m_data; }
	private:
		char* m_data;
};

创建这两个对象后,编译器(VC)给两个对象分配内存如下:

左边两个是类complex在调试模式和release模式下的编译器内存分配。在debug模式下,编译器给complex对象内存插入了头和尾(红色部分),4*8 + 4大小的信息部分(灰色部分),绿色部分是complex对象实际占用的空间,计算后只有52字节,但VC以16字节对齐,所以52最近的16倍数是64,还应该填补12字节的空缺(青色pad部分)。对于release部分的complex对象,只添加了信息头和伟部分。string类的分析基本一样。

接下来看对于数组对象,VC编译器是如何分配的:

类似的,编译器给对象增加了一些冗余信息部分,对于complex类对象,由于数组有三个对象,则存在8个double,然后编译器在3个complex对象前插入“3”用于标记对象个数。String类的分析方法也类似。

下面这张图说明了为何删除数组对象需要使用delete[]方法:

String类

String.h

#ifndef __MYSTRING__
#define __MYSTRING__

//结构
class String
{
public:                                 
   String(const char* cstr=0);                     
   String(const String& str);                    
   String& operator=(const String& str);         
   ~String();                                    
   char* get_c_str() const { return m_data; }
private:
   char* m_data;
};

#include <cstring>

//构造函数
inline
String::String(const char* cstr = 0)
{
   if (cstr) {//判断传入指针是否为空
      m_data = new char[strlen(cstr)+1];//开辟内存空间 + ‘\0’
      strcpy(m_data, cstr);//传进来的初值kao bei dao
   }
   else {   
      m_data = new char[1];
      *m_data = '\0';
   }
}
//析构函数
inline
String::~String()
{
   delete[] m_data;//删除
}
//拷贝构造函数
inline
String& String::operator=(const String& str)
{
   if (this == &str)
      return *this;

   delete[] m_data;//先把自己杀掉
   m_data = new char[ strlen(str.m_data) + 1 ];//开辟内存空间
   strcpy(m_data, str.m_data);//来源端拷贝目的端
   return *this;
}

inline
String::String(const String& str)
{
   m_data = new char[ strlen(str.m_data) + 1 ];
   strcpy(m_data, str.m_data);
}

#include <iostream>
using namespace std;

ostream& operator<<(ostream& os, const String& str)
{
   os << str.get_c_str();
   return os;
}

#endif

String.cpp

#include "string.h"
#include <iostream>

using namespace std;

int main()
{
  String s1("hello"); 
  String s2("world");
    
  String s3(s2);
  cout << s3 << endl;
  
  s3 = s1;
  cout << s3 << endl;     
  cout << s2 << endl;  
  cout << s1 << endl;      
}

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值