• 2-4:析构函数与构造函数中使用动态内存


    在析构函数与构造函数中使用动态内存

    1.析构函数的使用

    (1)析构函数在对象对销毁时自动调用,一般有2种情况
    (2)用new分配的对象,用delete显式析构
    (3)分配在栈上的对象,当栈释放时自动析构
    (4)普通情况下析构函数都是空的,因为不必做什么特别的事情

    2.在class中使用动态内存变量

    (1)什么情况下用动态内存?
       需要大块内存,且需要按需灵活的申请和释放,用栈怕爆、用全局怕浪费和死板时
    (2)在class person中增加一个int *指针,用于指向一个int类型元素的内存空间
    (3)在构造函数中分配动态内存
    (4)在析构函数中回收动态内存
    (5)将动态内存从int变量升级到int数组变量
    (6)实战中C++常用的动态内存往往是容器vector那些

    3.用valgrind工具查看内存泄漏

    实际开发中,程序较复杂时,可能会出现内存泄漏,可以使用工具检测

    (1)valgrind工具介绍:参考:https://blog.csdn.net/u012662731/article/details/78652651
    (2)安装:sudo apt-get install valgrind(ubuntu16.04 X64)
    (3)编译程序:主要是添加-g参数便于调试时有行号  g++ person.cpp main.cpp -g -o apptest
    (4)使用:valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes ./app
     1 #include "person.hpp"
     2 
     3 using namespace MAN;
     4 
     5 
     6 int main(void)
     7 {
     8     // 人的一天的生活
     9     string s1 = "linux";
    10     person pPerson(s1);            // 创建了一个person的对象,分配在栈上
    11 //    person lisi;
    12 
    13 //    pPerson->name = "zhangsan";
    14     pPerson.age = 23;
    15     pPerson.male = 1;
    16     //    pPerson->p = malloc(256);
    17 
    18     pPerson.eat();
    19     pPerson.work();
    20     pPerson.eat();
    21     pPerson.work();
    22     pPerson.sleep();
    23 
    24     // 用完对象后就销毁它
    25     //    delete pPerson;
    26 
    27 
    28 #if 0
    29     // 人的一天的生活
    30     string s1 = "linux";
    31     person* pPerson = new person(s1);            // 创建了一个person的对象,分配在堆上
    32 //    person lisi;
    33 
    34 //    pPerson->name = "zhangsan";
    35     pPerson->age = 23;
    36     pPerson->male = 1;
    37     //    pPerson->p = malloc(256);
    38 
    39     pPerson->eat();
    40     pPerson->work();
    41     pPerson->eat();
    42     pPerson->work();
    43     pPerson->sleep();
    44 
    45     // 用完对象后就销毁它
    46     delete pPerson;
    47 #endif
    48 
    49 
    50     return 0;
    51 }
    main.cpp
     1 #ifndef __PERSON_H__
     2 #define __PERSON_H__
     3 
     4 
     5 #include <string>
     6 using namespace std;
     7 
     8 namespace MAN
     9 {
    10 
    11 
    12     // 声明这个类
    13     class person
    14     {
    15         // 访问权限
    16     public:
    17         // 属性
    18         string name;            // 名字
    19         int age;                // 年龄
    20         bool male;                // 性别,男为true,女为false
    21         int* pInt;                // 只是分配了p本身的4字节内存,并没有分配p指向的空间内存
    22 
    23         // 构造和析构
    24         person();                // 默认构造函数
    25         person(string name);    // 自定义构造函数
    26 
    27         ~person();                // 默认析构函数
    28 
    29         // 方法
    30         void eat(void);
    31         void work(void);
    32         void sleep(void);
    33 
    34 
    35     private:
    36 
    37     };
    38 
    39 }            // end of namespace MAN
    40 
    41 
    42 
    43 #endif
    44 
    45 #pragma once
    person.hpp
     1 #include "person.hpp"
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 
     7 // class的成员函数中可以引用class的成员变量,但是要考虑public和private这些
     8 void MAN::person::eat(void)
     9 {
    10     cout << name << " eat" << endl;
    11 }
    12 
    13 void MAN::person::work(void)
    14 {
    15     //    cout << "person work" << endl;
    16     if (this->male)
    17     {
    18         cout << this->name << " coding" << endl;
    19     }
    20     else
    21     {
    22         cout << this->name << " shopping" << endl;
    23     }
    24 }
    25 
    26 
    27 void MAN::person::sleep(void)
    28 {
    29     //    cout << "value of this->pInt = " << *(this->pInt) << endl;
    30     for (int i = 0; i < 10; i++)
    31     {
    32         this->pInt[i] = i;
    33     }
    34 
    35     for (int i = 0; i < 10; i++)
    36     {
    37         cout << "pInt[" << i << "] = " << pInt[i] << endl;
    38     }
    39 
    40     cout << this->name << " sleep" << endl;
    41 }
    42 
    43 
    44 MAN::person::person()
    45 {
    46     // 默认构造函数是空的
    47     cout << "default constructor" << endl;
    48 }
    49 
    50 MAN::person::person(string name)
    51 {
    52     // 默认构造函数是空的
    53     this->name = name;            // 构造对象后,同时对对象中的name属性进行初始化
    54 
    55     // 在构造函数中对class中需要分配动态内存的指针进行动态分配
    56 //    this->pInt = new int(55);
    57     this->pInt = new int[10];        // 分配了100个元素的数组
    58 
    59     cout << "userdefined constructor" << endl;
    60 }
    61 
    62 
    63 MAN::person::~person()
    64 {
    65     // 默认析构函数是空的
    66 //    delete this->pInt;                // 释放单个内存
    67     delete[] this->pInt;            // 释放数组内存
    68 
    69     cout << "userdefined destructor" << endl;
    70 }
    person.cpp
  • 相关阅读:
    全文本搜索神器
    唯一索引和普通索引怎么选择
    程序员应不应该搞全栈
    c 的陷阱
    抽象能力
    电影电视剧推荐
    系统故障诊断
    一次web网站被入侵的处理记录
    Spark RDD 操作
    (转)Mysql哪些字段适合建立索引
  • 原文地址:https://www.cnblogs.com/y4247464/p/13701969.html
Copyright © 2020-2023  润新知