Loading...
墨滴

木杉乀

2021/05/04  阅读:12  主题:全栈蓝

构造与析构

c++_构造与析构

构造函数

构造函数是一种特殊的函数

主要用来在创建对象时初始化对象, 即为对象的成员变量附初始值. 

也可以将对象在创建之初需要执行的逻辑写在构造函数中
构造函数:
  1. 构造函数的函数名和类名相同
  2. 构造函数没有函数返回值(没有返回值类型)
  3. 构造函数可以重载
构造函数的调用时机:
  1. 对象产生时自动调用(定义对象, 动态内存分配时)

    class MyNode
    {

     int id;
     char* name;
    public:
     MyNode(int a) {
      MyNode::id = a;
      MyNode::name = nullptr;
      printf("以调用有参构造函数:id:%d, name:%d\n", MyNode::id, MyNode::name);
     }
     MyNode() {
      MyNode::id = 0;
      MyNode::name = nullptr;
      printf("以调用无参构造函数:id:%d, name:%d\n", MyNode::id, MyNode::name);
     }
    };

    int main()
    {
     // 无参构造自动调用
     MyNode MuShan;
     MyNode* muShan = new MyNode;
     // 有参构造自动调用
     MyNode mushan(10);
     MyNode* Mushan = new MyNode(10);
     int a; //加断点-无效代码
     return 0;
    }
构造函数的特点:
  1. 如果一个类中没有显式的构造函数, 系统将自动分配一个缺省的 (隐式) 什么都不干的构造函数
 // 例
 class CA{
     int a;
 public:
     void setA();
 };// 此处没有构造函数
 int main()
 
{
     CA a; // 此时系统自动调用一个隐藏起来看不见的, 什么都不干的构造函数
 }
 // 这个隐藏的构造函数大概长这个样子--> 
 // CA(){}
  1. 如果类中有多个构造函数, 那么通常会有不同的参数列表和函数体

  2. 如果用户已经提供类无参(有参)构造, 那么系统将不再提供默认构造

  3. 类中如果只有有参构造, 但没有无参构造, 由于系统不再提供默认构造, 定义类时将必须带参, 否则会报错

拷贝构造

拷贝构造是一种特殊的带参构造函数, 参数为同类型类对象, 用于同类型对象的初始化
基础用法:
int main()
{
 int a = 10;
 int b(a);
 cout << b;
}
拷贝构造的特点:
  1. 如果没写拷贝构造, 系统将会提供一个隐式的拷贝构造, 这个拷贝构造将会把参数对象中的数据成员一个一个的赋值给自身的数据成员上

b的值和a相同, 但也出现问题(a中的成员s和b中的成员s指向同一个地址, 如果a.s改变b.s也会随之改变)

  1. 自定义拷贝构造
 类名 (const 类名& 引用名 ) { }

浅拷贝(默认拷贝构造就是一种看不见的系统自动调用的浅拷贝)

MyStu::MyStu(const MyStu& other)
{
 id = other.id;
 name = other.name;
}

深拷贝: (可以解决默认拷贝构造两指针指向同一内存)

MyStu::MyStu(const MyStu& other) // 深拷贝
{
 id = other.id;
 if (other.name == nullptr)
  name = nullptr;
 else
 {
  int length = strlen(other.name);
  name = new char[length + 1];
  strcpy(name, other.name);
 }
 name = other.name;
}
  1. 拷贝构造只有一个, 不存在函数重载
拷贝构造的调用:
  1. 显式拷贝构造调用;

  2. 隐式拷贝构造调用;

 int main()
 
{
  MyStu m;
  MyStu m1(m);  //拷贝构造的显式调用
  MyStu m2 = m;  //拷贝构造的隐式调用
  MyStu m3;
  m3 = m;    //重载赋值
  return 0;
 }
拷贝构造的调用时机:
  1. 在函数传参时,函数的形参是类对象

  2. 如果一个函数的返回值类型是类类型, 在函数调用结束时, 返回对象的时候

 MyStu fun(MuStu s) {return s;}
 // 发生两次拷贝构造调用

析构函数

析构函数也是一种特殊的构造函数
主要功能是在对象声明周期结束时做一些清理工作
将对象生命周期最后要做的事情写在析构函数中

构造函数:

  1. 函数名和类名相同, 函数名前加~
  2. 没有返回值类型, 也没有参数列表
  3. 如果类中没有自己写析构, 系统自动提供一个什么都不干的隐式的析构

析构的调用时机:

  1. 在对象死亡时自动调用(对象作用域结束, 动态内存被释放)
  2. 析构函数可以主动通过对象调用,析构函数必须是公有属性下
class MyStu {
 int id;
 char* name;
public:
 ~MyStu();     // 析构函数
};

MyStu::~MyStu()     // 析构(释放清理类对象的函数)
{
 if (name)
  delete[] name;
 name = nullptr;
}

木杉乀

2021/05/04  阅读:12  主题:全栈蓝

作者介绍

木杉乀