zoukankan      html  css  js  c++  java
  • 第19课

    第19课 - 对象的构造(下)

    1. 特殊的构造函数

      (1)无参构造函数

        当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空。

      (2)拷贝构造函数

        当类中没有定义拷贝构造函数时,编译器默认提供一个拷贝构造函数简单的进行成员变量的值复制

     1 #include <stdio.h>
     2 
     3 class Test
     4 {
     5 private:
     6     int i;
     7     int j;
     8 public:
     9     int getI()
    10     {
    11         return i;
    12     }
    13     int getJ()
    14     {
    15         return j;
    16     }
    17 
    18     Test(const Test& t)
    19     {
    20         i = t.i;
    21         j = t.j;
    22     }
    23 
    24     /*
    25     Test()
    26     {
    27     }
    28     */
    29 };
    30 
    31 int main()
    32 {
    33     Test t1;
    34 
    35     /*
    36     Test t2 = t1;
    37 
    38     printf("t1.i = %d, t1.j = %d
    ", t1.getI(), t1.getJ());
    39     printf("t2.i = %d, t2.j = %d
    ", t2.getI(), t2.getJ());
    40     */
    41 
    42     return 0;
    43 }
    特殊的构造函数

    2. 拷贝构造函数

    2.1 拷贝构造函数的意义

      (1)兼容 C 语言的初始化方式     int i = 1;    int j = i;

      (2)初始化行为能够符合预期的逻辑

      (3)深拷贝浅拷贝

        ① 浅拷贝:拷贝后对象的物理状态相同  【编译器提供的拷贝构造函数只提供浅拷贝】

        ② 深拷贝:拷贝后对象的逻辑状态相同

     1 #include <stdio.h>
     2 
     3 class Test
     4 {
     5 private:
     6     int i;
     7     int j;
     8     int* p;
     9 
    10 public:
    11     int getI(){return i;}
    12 
    13     int getJ(){return j;}
    14 
    15     int* getP(){return p;}
    16 
    17     /*
    18     //拷贝构造函数
    19     Test(const Test& t)
    20     {
    21         i = t.i;
    22         j = t.j;
    23         p = new int;
    24 
    25         *p = *t.p;
    26     }
    27     */
    28 
    29     
    30     //带参构造函数
    31     Test(int v)
    32     {
    33         i = 1;
    34         j = 2;
    35         p = new int;
    36         
    37         *p = v;
    38     }
    39 
    40     ~Test(){delete p;}
    41     
    42 };
    43 
    44 int main()
    45 {
    46     Test t1(3);  //调用Test(int v);
    47     Test t2(t1); //调用Test(const Test& t)
    48 
    49     printf("t1.i = %d, t1.j = %d, *t1.p = %d
    ", t1.getI(), t1.getJ(), *t1.getP());
    50     printf("t2.i = %d, t2.j = %d, *t2.p = %d
    ", t2.getI(), t2.getJ(), *t2.getP());
    51 
    52     return 0;
    53 }
    对象的初始化

    2.2 什么时候需要进行深拷贝?

      (1)对象中有成员指向了系统中的资源

      • 成员指向了动态内存空间
      • 成员打开了外存中的文件
      • 成员使用了系统中的网络端口
      • ......

      (2)问题分析

      

    ★★★一般性原则:自定义拷贝构造函数的时候,必须思考这个拷贝函数是否需要实现深拷贝?  如果不需要,为什么不使用编译器提供的拷贝构造函数?

    【编程实验】数组类的改进

     1 #ifndef _INTARRAY_H_
     2 #define _INTARRAY_H_
     3 
     4 class IntArray
     5 {
     6 private:
     7     int m_length;
     8     int* m_pointer;
     9 
    10 public:
    11     IntArray(int len);
    12     IntArray(const IntArray& obj);
    13     ~IntArray();
    14 
    15     int length();
    16     bool get(int index, int& value);
    17     bool set(int index, int value);
    18 };
    19 
    20 #endif
    IntArray.h
     1 #include "IntArray.h"
     2 
     3 IntArray::IntArray(int len)
     4 {
     5     m_pointer = new int[len];
     6 
     7     for(int i = 0; i<len; i++)
     8     {
     9         m_pointer[i] = 0;
    10     }
    11 
    12     m_length = len;
    13 }
    14 
    15 IntArray::IntArray(const IntArray& obj)
    16 {
    17     m_length = obj.m_length;
    18 
    19     m_pointer = new int[obj.m_length];
    20 
    21     for (int i = 0;i < obj.m_length; i++)
    22     {
    23         m_pointer[i] = obj.m_pointer[i];
    24     }
    25 }
    26 
    27 IntArray::~IntArray()
    28 {
    29     if(m_pointer)
    30     {
    31         delete[] m_pointer;
    32     }
    33 }
    34 
    35 int IntArray::length()
    36 {
    37     return m_length;
    38 }
    39 
    40 bool IntArray::get(int index, int& value)
    41 {
    42    bool bRet = (0 <= index) && (index <m_length);
    43 
    44    if(bRet)
    45    {
    46         value = m_pointer[index];
    47    }
    48 
    49    return bRet;
    50 }
    51 
    52 bool IntArray::set(int index, int value)
    53 {
    54 
    55    bool bRet = (0 <= index) && (index <m_length);
    56 
    57    if(bRet)
    58    {
    59         m_pointer[index] = value;
    60    }
    61 
    62    return bRet;
    63 }
    IntArray.cpp
     1 #include <stdio.h>
     2 #include "IntArray.h"
     3 
     4 int main()
     5 {
     6     IntArray a(5);//调用带参构造函数
     7     
     8     for(int i=0; i<a.length(); i++)
     9     {
    10         a.set(i, i + 1);
    11     }
    12 
    13     for(int i=0; i<a.length(); i++)
    14     {
    15         int value = 0;
    16 
    17         if(a.get(i, value))
    18         {
    19             printf("a[%d] = %d
    ", i, value);
    20         }
    21     }
    22 
    23     IntArray b = a; //调用拷贝构造函数
    24     
    25     for(int i=0; i<b.length();i++)
    26     {
    27         int value = 0;
    28 
    29         if(b.get(i, value))
    30         {
    31             printf("b[%d] = %d
    ", i, value);
    32         }
    33     }
    34     return 0;
    35 }
    main.cpp

    3. 小结

      (1)C++ 编译器会默认提供构造函数

      (2)无参构造函数用于定义对象的默认初始状态

      (3)拷贝构造函数在创建对象时拷贝对象的状态

      (4)对象的拷贝有浅拷贝深拷贝两种方式。浅拷贝使得对象的物理状态相同;深拷贝使得对象的逻辑状态相同。

        

  • 相关阅读:
    第28月第23天 lineFragmentPadding
    第28月第22天 iOS动态库
    第28月第21天 记事本Unicode 游戏编程中的人工智能技术
    第28月第11天 vim -b
    第28月第10天 iOS动态库
    第28月第8天
    第28月第7天 本地摄像头方向
    第28月第5天 uibutton交换方法
    第28月第4天 __bridge_transfer
    python __getattr__ __setattr__
  • 原文地址:https://www.cnblogs.com/shiwenjie/p/7231721.html
Copyright © 2011-2022 走看看