zoukankan      html  css  js  c++  java
  • 4.2构造函数4.3析构函数

    5.3构造函数和析构函数

    构造函数是用于创建对象的特殊成员函数。

    当创建对象时,系统自动调用构造函数

    构造函数的作用是:

    为对象分配空间;对数据成员赋初值;请求其他资源

    没有用户定义的构造函数时,系统提供缺省版本的构造函数。

    构造函数名与类名相同:类名

    构造函数可以重载。

    构造函数可以有任意类型的参数,但没有返回类型。

    //所有的类默认都有要给构造函数,一个析构函数

    //构造函数、析构函数可以重载

    //构造函数、析构函数没有返回值

    先初始化,后赋值

     1 class myclass
     2 {
     3 public:
     4     int num;
     5 public:
     6     myclass() :num(4)//先初始化
     7     {
     8         num = 10;//后赋值
     9         std::cout << "class create" << std::endl;
    10     }
    11 };

    深拷贝

     1 #define _CRT_SECURE_NO_WARNINGS
     2 #include <iostream>
     3 
     4 class string
     5 {
     6 public:
     7     char *p;
     8     int length;
     9     string(int num, char *str)
    10     {
    11         length = num;//获取长度
    12         p = new char[length];//分配内存
    13         memset(p, 0, length);//清空
    14         strcpy(p, str);//拷贝内容
    15     }
    16     string(const string & string1)//深拷贝
    17     {
    18         this->p = new char[string1.length];//分配内存
    19         this->length = string1.length;//赋值
    20         memset(this->p, 0, this->length);//清空
    21         strcpy(this->p, string1.p);//拷贝内容
    22     }
    23     ~string()
    24     {
    25         delete[]p;
    26     }
    27 };
    28 
    29 void main()
    30 {
    31     string *pstr1 = new string(10, "hello");
    32 
    33     std::cout << pstr1->p << std::endl;
    34 
    35     string *pstr2 = new string(*pstr1);//深拷贝
    36 
    37     std::cout << pstr2->p << std::endl;
    38 
    39     delete pstr1;
    40 
    41     std::cout << pstr2->p << std::endl;
    42 
    43     system("pause");
    44 }

    //不要重复delete

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     int num = 10;//栈上
     7     
     8     int *p = new int;//堆上
     9     *p = 5;
    10 
    11     std::cout << *p << " " << p << std::endl;
    12 
    13     delete p;
    14     delete p;//不要重复delete
    15 
    16     system("pause");
    17 }

    p = NULL;//防止重复删除

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     int *p = new int;
     7 
     8     delete p;
     9 
    10     p = NULL;//防止重复删除
    11 
    12     delete p;
    13     
    14     system("pause");
    15 }

    int *p = new int[80];//new只能分配线性

    int(*px)[10] = (int(*)[10])p;//二维数组

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     int *p = new int[80];//new只能分配线性
     7 
     8     int(*px)[10] = (int(*)[10])p;//二维数组
     9 
    10     int data = 0;
    11 
    12     for (int i = 0; i < 8; i++)
    13     {
    14         for (int j = 0; j < 10; j++)
    15         {
    16             px[i][j] = data++;
    17             std::cout << " " << px[i][j];
    18         }
    19         std::cout << endl;
    20     }
    21 
    22     system("pause");
    23 }

    //空类占1个字节,表示自己存在

    //类的对象,数据是独立的,代码是共享的

    //没有分配内存,构造函数没有意义

     1 #include <iostream>
     2 using namespace std;
     3 
     4 //空类占1个字节,表示自己存在
     5 //类的对象,数据是独立的,代码是共享的
     6 //没有分配内存,构造函数没有意义
     7 
     8 class myclass
     9 {
    10 public:
    11     myclass();
    12     ~myclass();
    13 };
    14 
    15 void main()
    16 {
    17     std::cout << sizeof(myclass) << std::endl;//1
    18 
    19     system("pause");
    20 }

    全局重载new重载delete

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void *operator new(size_t size)
     5 {
     6     std::cout << "全局被调用,内存被分配" << std::endl;
     7     if (!size)
     8     {
     9         return NULL;
    10     }
    11     else
    12     {
    13         void *p = malloc(size);
    14         return p;
    15     }
    16 }
    17 
    18 void operator delete(void *p)
    19 {
    20     std::cout << "全局被调用,内存被释放" << std::endl;
    21     free(p);
    22 }
    23 
    24 void main()
    25 {
    26     int *p = new int;
    27 
    28     delete p;
    29 
    30     system("pause");
    31 }

    重载new delete数组

      1 #include <iostream>
      2 using namespace std;
      3 
      4 //全局new delete监视所有分配释放
      5 //局部new delete监视某个类的分配释放
      6 
      7 void *operator new(size_t size)//全局重载new
      8 {
      9     if (!size)
     10     {
     11         return NULL;
     12     }
     13     else
     14     {
     15         std::cout << "全局被调用,内存被分配" << std::endl;
     16         void *p = malloc(size);
     17         return p;
     18     }
     19 }
     20 
     21 void operator delete(void *p)//全局重载delete
     22 {
     23     std::cout << "全局被调用,内存被释放" << std::endl;
     24     free(p);
     25 }
     26 
     27 void *operator new[](size_t size)//全局重载new数组
     28 {
     29     return operator new(size);//每个对象挨个调用已经重载好的new,调用构造函数
     30 }
     31 
     32 void operator delete[](void *p)//全局重载delete数组
     33 {
     34     return operator delete(p);//每个对象挨个调用已经重载好的delete,调用析构函数
     35 }
     36 
     37 class tansheng
     38 {
     39     int *p;
     40     int length;
     41 public:
     42     static int count;//计数器
     43 
     44     tansheng()
     45     {
     46         std::cout << "tansheng被创建" << std::endl;
     47     }
     48 
     49     ~tansheng()
     50     {
     51         std::cout << "tansheng被销毁" << std::endl;
     52     }
     53 
     54     static void * operator new(size_t size)//局部重载new
     55     {
     56         //局部new和全局new分别调用构造函数一次,只有一次有效,因此只有一个指针
     57         count++;
     58     std::cout << "对象被创建" << std::endl;
     59     tansheng *ptem = ::new tansheng;//全局new
     60     return ptem;
     61     }
     62 
     63     static void * operator new[](size_t size)//局部重载new数组
     64     {
     65         std::cout << "对象数组被创建" << std::endl;
     66         return operator new(size);
     67     }
     68 
     69     static void operator delete(void *p)//局部重载delete
     70     {
     71         count--;
     72         std::cout << "对象被销毁" << std::endl;
     73         ::delete p;//全局delete
     74     }
     75 
     76     static void operator delete[](void *p)//局部重载delete数组
     77     {
     78         std::cout << "对象数组被销毁" << std::endl;
     79         return operator delete(p);
     80     }
     81 };
     82 
     83 int tansheng::count = 0;//初始化静态数据成员
     84 
     85 //对象数组被创建
     86 //对象被创建
     87 //全局被调用,内存被分配
     88 //tansheng被创建
     89 //tansheng被创建
     90 //tansheng被创建
     91 //tansheng被创建
     92 //tansheng被创建
     93 //tansheng被创建
     94 //tansheng被销毁
     95 //tansheng被销毁
     96 //tansheng被销毁
     97 //tansheng被销毁
     98 //tansheng被销毁
     99 //对象数组被销毁
    100 //对象被销毁
    101 //全局被调用,内存被释放
    102 //请按任意键继续. . .
    103 
    104 void main()
    105 {
    106     tansheng *p = new tansheng[5];
    107 
    108     delete[]p;
    109 
    110     system("pause");
    111 }

    new限定区域分配内存的语法

    //p1,p3作为指针变量在栈区,存储的地址指向堆区

    //手动释放内存

    //p2,p4作为指针变量在栈区,存储的地址在静态区,缓冲区

    //自动释放内存,用于分配用完了就不会再用的数据

    //避免了内存泄露,牺牲了内存访问的独立性

    //可以看到p1,p3的内存地址一直不同,p2,p4的内存地址一直在某个区域

     1 #include <iostream>
     2 using namespace std;
     3 
     4 const int buf(512);//限定一个常量整数512
     5 int N(5);//数组长度
     6 char buffer[buf];//在静态区
     7 
     8 //p1,p3作为指针变量在栈区,存储的地址指向堆区
     9 //手动释放内存
    10 
    11 //p2,p4作为指针变量在栈区,存储的地址在静态区,缓冲区
    12 //自动释放内存,用于分配用完了就不会再用的数据
    13 //避免了内存泄露,牺牲了内存访问的独立性
    14 
    15 //可以看到p1,p3的内存地址一直不同,p2,p4的内存地址一直在某个区域
    16 
    17 void main()
    18 {
    19     double *p1, *p2;
    20 
    21     for (int l = 0; l < 3; l++)
    22     {
    23         p1 = new double[N];//分配内存,N个元素大小
    24 
    25         p2 = new (buffer)double[N];//指定区域分配内存
    26 
    27         for (int i = 0; i < N; i++)
    28         {
    29             p1[i] = p2[i] = i + 10.8 + l;
    30             std::cout << "p1==" << &p1[i] << " " << p1[i];
    31             std::cout << " p2==" << &p2[i] << " " << p2[i] << std::endl;
    32         }
    33 
    34         std::cout << std::endl;
    35     }
    36     
    37     double *p3, *p4;
    38 
    39     p3 = new double[N];//分配内存,N个元素大小
    40 
    41     p4 = new (buffer)double[N];//指定区域分配内存
    42 
    43     for (int i = 0; i < N; i++)
    44     {
    45         p3[i] = p4[i] = i + 10.8;
    46         std::cout << "p3==" << &p3[i] << " " << p3[i];
    47         std::cout << " p4==" << &p4[i] << " " << p4[i] << std::endl;
    48     }
    49 
    50     system("pause");
    51 }

    malloc free和new delete的区别

    //malloc和free只会分配内存、释放内存,不会对内存进行操作,不调用构造函数、析构函数

    //new和delete自动调用构造函数、析构函数

     1 #include <iostream>
     2 
     3 class myclass
     4 {
     5 public:
     6     int x;
     7     int y;
     8 public:
     9     myclass();//构造函数
    10     ~myclass();//析构函数
    11 };
    12 
    13 myclass::myclass()//构造函数
    14 {
    15     std::cout << "被构造" << std::endl;
    16 }
    17 
    18 myclass::~myclass()//析构函数
    19 {
    20     std::cout << "被销毁" << std::endl;
    21 }
    22 
    23 void main()
    24 {
    25     //malloc和free只会分配内存、释放内存,不会对内存进行操作,不调用构造函数、析构函数
    26     myclass *p1 = (myclass *)malloc(sizeof(myclass));
    27     free(p1);
    28 
    29     //new和delete自动调用构造函数、析构函数
    30     myclass *p2 = new myclass;
    31     delete p2;
    32 
    33     system("pause");
    34 }

    //初始化列表不可以有this

    //error C2059: 语法错误:“this”

     1 class mycomplex
     2 {
     3 public:
     4     int x;
     5     int y;//xy坐标
     6 
     7     //没有构造,无法使用this初始化
     8     mycomplex(int x, int y) :this->x = x, this->y = y//error C2059: 语法错误:“this”
     9     {
    10 
    11     }
    12     ~mycomplex()
    13     {
    14 
    15     }
    16 };

    //初始化列表不可以有this

    解决办法:

     1 class mycomplex
     2 {
     3 public:
     4     int x;
     5     int y;//xy坐标
     6 
     7     mycomplex(int x, int y)
     8     {
     9         this->x = x;
    10         this->y = y;
    11     }
    12     ~mycomplex()
    13     {
    14 
    15     }
    16 };
  • 相关阅读:
    程序员怎么提高英语阅读水平【转】
    Linux后台执行【转】
    pcre安装错误的解决方法
    编译PHP错误:undefined reference to `ts_resource_ex'
    apache2启动时共享库libpcre找不到
    设置Ubuntu的IP地址
    vsftp 的应用
    用Python实现动态的切换桌面背景
    DNN 4.x CodeSmith模板
    如何在DNN中使用Google Analytics
  • 原文地址:https://www.cnblogs.com/denggelin/p/5645555.html
Copyright © 2011-2022 走看看