C++ 动态内存分配(二十)


析构函数: 类成员指向 new分配的内存,当类过期时,成员指针也将过期,但成员指向的内存仍被分配,除非使用 delete 将其释放;删除类可以释放类本身占用的内存,但并不能释放属于类对象成员指针所指向的内存,因为必须使用析构函数,在析构函数中使用 delete 语句,可以确保类过期时由构造函数使用 new 分配的内存被释放。

警告:new[] 对应 delete[]

深复制:两个独立的内存空间,值相同,如果类中包含了使用 new 初始化的指针成员,应当定义一个复制构造函数

浅复制:只是复制指针值和指针信息,没有额外开辟内存空间


hpp

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

using namespace std;

class StringBad {
    char *str;
    int len;
    static int num;
    
public:
    
    float f;
    
   //构造函数
    StringBad();
    StringBad(const char *s);
    //带实参构造函数
    StringBad(const char *s = "dfsdaa", int i = 200)
    {
        len = i;
        str = new char[strlen(s)+1];
        strcpy(str, s);
        
    }
    
    
    //析构函数
    ~StringBad();
    
    //friend function
    friend ostream & operator<<(ostream & os ,StringBad & sb);
    
    
    
};



class Test {
    
    
public:
    float f;
    int   i;
    
    Test(const float a = 33.5f , int b = 999)
    {
        f = a;
        i = b;
    }
    
    ~Test()
    {
        cout << "~Test()" << endl;
    }
    
    void show(){ cout << f << endl << i << endl;  };
    
};


cpp

int StringBad::num = 0;

#pragma mark - 构造函数
StringBad::StringBad()
{
    len = 8;
    str = new char[len+1];
    strcpy(str, "C++");
    
    cout << num++ << endl;
    
}


StringBad::StringBad(const char *s)
{
    
    size_t i = strlen(s);  //字符串长度,不包含最后的空白字符
    str = new char[i+1];
    strcpy(str, s);   // str = s 错误,因为str是指针,不保存s字符串,s字符串保存在堆内存中,str只是指定内存地址的指针变量
    
    num++;
    cout << num << endl;

}


#pragma mark - 友元
ostream & operator<<(ostream & os , StringBad &sb)
{
    
    os << sb.str << endl;
    
    return os;
}


#pragma mark - 析构函数
StringBad::~StringBad()
{
    cout << num-- << endl;
    delete [] str;
}


main

#include <iostream>
#include "MemeryFile.hpp"

const int buffer = 512;

int main(int argc, const char * argv[]) {
    
    
    StringBad *s;
    
    Test *t1 , *t2 ,*t3 ,*t4;
    
    char *buf = new char[buffer];
    
    //1、定位new,在相邻的内存单元中创建两个对象
    t1 = new (buf) (Test);
    t2 = new (buf+sizeof(Test))(Test);
    
    t1->show();
    t2->show();
    
    
    //2、常规new 运算
    t3 = new Test();
    t4 = new Test();
    
    
    //释放内存
    //定位new 需要手动调用析构函数
    t1->~Test();
    t2->~Test();
    
    //常规new 的释放内存
    delete t3;
    delete t4;
    
    
    //打印
    /**
     33.5
     999
     33.5
     999
     ~Test()
     ~Test()
     ~Test()
     ~Test()

     */
    

    return 0;
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值