[C++潜心修炼]类与对象:构造与析构与拷贝构造


构造函数

         在玩C时会遇到用数据结构的时候,每次用都要初始化,非常麻烦,且有时还会忘记初始化导致一些问题(如链表不初始化,他next不指向空那么就出问题了)

默认构造:和类同名没有返回值

class Data
{
    
    
   Data()
   {
    
    
   
    }
  
  
}

构造函数也可以代参,且他也支持函数重载呦

class Data
{
    
    
  public:
  Data(int day)
   {
    
    
     _day=day;
    }
   Data(double day)
   {
    
    
     _day=day;
    }
   private:
  int _day;
  
}

C++中的函数缺省参数咋在这里也适用,缺省构造函数

class Data
{
    
    
  public:
  Data(int day=1)
   {
    
    
     _day=day;
    }
   private:
  int _day;
  
}

​          缺省构造也是默认构,在一个类中只能有一个默认的构造函数呦(一山不容二虎,除非一公多母系列),但可以有多个带参的构造函数,一般建议都建议写缺省的,毕竟一个完成了俩个构造函数的事

其实他有一些性质

         当你如果不写默认构造函数的时候编译器会自能生成(取决于编译器Clion是随机值,CoderRununer是0/0/0),但是他初始化是随机值。但是如果你的类中已经有了构造那么编译器就不生成了



补丁

他可以在变量声明的时候给他一个缺省参数

class Data
{
    
    
  
  previte:
  int _year=0;
  int _month=1;
  int _day=1;
};

当你不写的时候她就会和函数的缺省参数一样自动赋值

class Data
{
    
    
  
  previte:
  int *arr=(int*)malloc(sizeof(int)*2);
};

他还可以调用库函数给你开一块空间



构造列表

         其实在进入构造函数之前会有一个小插曲就是构造列表,他会先给数据初始化,默认情况下是不显示,不写构造函数那么编译器的自动生成一个,且不初始化本函数,其实不算太对,她其实会在构造函数初始化哪里初始化数据,加了补丁和掉默认构造差不多


用法 : 变量()

在这里插入图片描述


构造列表的一些性质

  • 不管你有没有写构造函数列表默认都会生成,在调用构造函数进入内部之前就先吧数据赋值了
  • 构造列表也可以调用函数
  • 且他每个变量只能初始化一次
  • const 的变量,引用成员变量,自定义成员变量且没有写默认构造函数的情况下需要构造列表
  • 声明次序与其在构造列表无关,如果声明先声明A,B,那么列表也会这样次序构造


析构函数

​          虽然用数据结构不出初始化会问题很大,但是你不释放你开辟的内存看起来很小,一个例子,不初始化就像是之间被射杀,而不释放就像是抽烟(或者每天给你吸一小口瓦斯),你每天抽累积起来,慢性的…………压死骆驼的永远不是最后一根稻草


作用:

他的作用就是释放调类中所动态开辟的内存

​           析构函数和构造函数一样不写的他调用编译器自己生成的,但是有一个比较难受的是他不会在本类中做任何事情,如果这个类中包含的另外的类的析构函数,也没有的话和外部类一样啥也不干

 ~Data() 
{
    
    
  
}:~
英:~  
看么中国的~多大气,可你不可以用它哦

他和析构函数一样但是前面多了个波浪号,这里要小心要英文输入法的


拷贝构造函数

​          我们总会遇到这样的场景,如结婚纪念日,生日……,备份这样的特殊日期,那么在C++中可以用拷贝构造来实现,如果没写编译器会自动生成,他会进行浅拷贝,把数据一个一个拷贝到数据(memcpy),中但是他有一个缺陷,后文说到

形势

Data(const Data d1)//明显这里和上面的有很大的不同,他的参数是构造函数
{
    
    
  
}

​          那么这里可以发现形参变成类一个类,那么形式参数是实参数的零时拷贝,那么形参也会开一块空间取拷贝,可是拷贝就会调用拷贝构造,拷贝构造又要参数,参数又要拷贝构造

点击查看源网页

所以要传引用之前或者指针,但是指针好麻烦的要 ‘*’你不累也可以用它

class Data
{
    
    
  public:
    Data(const Data&d1)
   {
    
    
       _year=d1.year;
      _month=d1.month;
      _day=d1.day;
   }
  private:
  int _year;
  int _month;
  int _day;
}

缺陷:
开下面的的场景
在这里插入图片描述

         那么在main函数结束的时候她就会调用析构,d2析构释放这块空间,d1还是指向这块空间,那么在析构就会报错



赋值拷贝构造

​           你生活中可能会可能一些日期是需要更改的,如出差日期之类的,如果是用类那么他是如何修改的呢?复制构造这里就用到 运算符重载operator =

class Data
{
    
    

  public:
   Data operator =(const &Data d1)//明显这里和上面的有很大的不同,他的参数是构造函数   
   {
    
    
     _year=d1.year;
      _month=d1.month;
      _day=d1.day;
   }
    
  private:
  int _year;
  int _month;
  int _day;
  
}

​           你会发现他和拷贝好像啊,确实逻辑是差不多,但是用处不一样,他们开头我写了生活中的场景哟,就是一个是开始需要记录一个日期,一个是后面突然需要记的日期

         如果不写编译器也会生成一个但是完成的事浅拷贝也就是位拷贝和拷贝构造一样

Supongo que te gusta

Origin blog.csdn.net/Legwhite/article/details/121060028
Recomendado
Clasificación