• 学习拷贝构造函数和赋值运算符


    拷贝构造函数在下面三种情况下被调用:

    1. 拷贝初始化,如:A b(a);
    2. 赋值初始化:如:A b = a;
    3. 函数传形参:如:foo(A a)

    赋值运算只有一种情况会被调用:

    1. 非初始化的赋值:如:A b; b = a;

    代码:

     1 #include <stdlib.h>
     2 #include <string>
     3 
     4 /***
     5 * @author:zanzan101
     6 */
     7 
     8 inline void P(const char* str)
     9 {
    10     printf("%s
    ", str);
    11 }
    12 
    13 class A
    14 {
    15 private: 
    16     int _data;
    17     char* _name;
    18 public:
    19     A(): _name(0)
    20     {
    21         P("调用构造函数");
    22     }
    23 
    24     // 拷贝构造函数
    25     // 无论构造函数还是拷贝构造函数,都要处理好对于指针的初始化,一般,应该一开始就对指针赋值为0,后面再进一步赋值
    26     // 对象的产生,究其根源只有两个途径:构造和拷贝构造,赋值运算的右值也是来自这两种途径
    27     A(A& a)
    28     {
    29         P("调用拷贝构造函数");
    30         _name = 0;
    31         _data = a._data;
    32         if(a._name)
    33         {
    34             _name = new char[strlen(a._name)+1];
    35             strcpy(_name, a._name);
    36         }
    37     }
    38 
    39     // 赋值运算符
    40     // 注意:返回值类型设为A&是为了实现a=b=c、(a=b)=c等操作
    41     A& operator= (A& a)
    42     {
    43         P("调用赋值运算符");
    44 
    45         if(this == &a)
    46             return *this;
    47 
    48         // 调用赋值运算的对象,必然已经经历过了构造或者拷贝构造
    49         // 因此,合理的设计构造和拷贝构造函数,会使_name为0或者其他有效值,不会出现0xCCCCCCCC的非法情况
    50         if(_name)
    51             delete _name;
    52 
    53         _data = a._data;
    54 
    55         if(!a._name)
    56             _name = 0;
    57         else
    58         {
    59             _name = new char[strlen(a._name)+1];
    60             strcpy(_name, a._name);
    61         }
    62         return *this;
    63     }
    64 };
    65 
    66 void foo(A a)
    67 {
    68     return;
    69 }
    70 int _tmain(int argc, _TCHAR* argv[])
    71 {
    72     P(">> 声明对象,但不初始化时:");
    73     A a;
    74 
    75     P(">> 声明对象同时用对象进行初始化时:");
    76     A b = a;
    77 
    78     P(">> 先声明对象:");
    79     A c;
    80     P(">> 再对对象进行赋值时:");
    81     c = a;
    82     
    83     P(">> 使用拷贝构造函数初始化时:");
    84     A d(a);
    85 
    86     P(">> 在函数调用传入形式参数时:");
    87     foo(a);
    88 
    89 
    90     system("pause");
    91     return 0;
    92 }

    输出:

    >> 声明对象,但不初始化时:
    调用构造函数
    >> 声明对象同时用对象进行初始化时:
    调用拷贝构造函数
    >> 先声明对象:
    调用构造函数
    >> 再对对象进行赋值时:
    调用赋值运算符
    >> 使用拷贝构造函数初始化时:
    调用拷贝构造函数
    >> 在函数调用传入形式参数时:
    调用拷贝构造函数
    请按任意键继续. . .
  • 相关阅读:
    Django模板系统
    __new__与__init__的区别
    django中models field详解
    快速入门mysql
    jq2
    jq
    前端 js 部分
    前端 js
    前端 css
    前端 table form
  • 原文地址:https://www.cnblogs.com/zanzan101/p/3406440.html
Copyright © 2020-2023  润新知