函数

[TOC]

函数

构造函数

  1. 通过类里函数可以给私有成员赋值,同时也可以通过函数return 出值

  2. 特殊的成员函数,主要用于创建对象时初始化对象->给对象成员赋予初值

  3. 构造函数的特点

    • 构造函数的函数名与类名相同
    • 构造函数没有返回值类型,也没有返回值
    • 构造函数可以重载
  4. 没有写构造函数,自己会生成,由于内联函数,牺牲时间换效率

    • 系统给的构造函数

      1
      Myclass(){}
  5. 系统给的构造函数相当于低保

  6. 构造函数,在创建时系统就会调用,不能通过对象调用构造函数

  7. 默认给的构造函数,是public类型

  8. const:改变性质,将变量变成常量

    • const修饰的变量在函数创建时进行赋值:

    • 是在初始化的时候赋初值,不是在声明的时候

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      #include<iostram>
      using namespace std;

      class chg
      {
      public:
      const int num1;
      const int num2;
      const int num3;
      chg();
      private:
      };

      chg::chg(int n,int i):num1(n),num2(i),num3(3)//括号里面可以是变量也可以是常量
      {

      }

      int main()
      {

      return 0;
      }

析构函数

  1. 一种特殊的函数,作用是在对象的生命周期结束时进行清理,系统可以自动调用析构函数
  2. 函数名与类名一致,在前面加上~
  3. 没有返回值,也没有参数,但必须有参数表也就是()
  4. 有低保,没写的话,系统自动分配
  5. 可以通过外部访问到析构函数
  6. 在类创建时,自动使用一次,构造,和析构(在生命周期结束时,会自动调用析构函数)
  7. 先构造的后析构

拷贝构造, 函数

  1. 先是构造函数,才可能是拷贝构造函数

  2. 有低保,系统会统一给

  3. 第一个参数是,该类的对象

    操作实例:

    1
    2
    3
    4
    5
    6
    class Myclass()
    {
    Myclass();//构造函数
    ~Myclass();//析构函数
    Myclass(Myclass& obj);//拷贝构造函数
    }
  4. 调用时机

    • 使用一个对象给另一个对象进行初始化

    • 使用一个对象构造另一个对象

    • 函数的参数是类的对象

    • 返回值是类

      实例:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      class zjy
      {

      }

      void zjy2()
      {
      zjy zjy3;//进行无参构造

      return zjy3;//由于zjy3存在于栈区,所以函数结束会被回收,因此返回值是zjy3的复制体,此时调用了拷贝构造
      }



      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      class zjy
      {
      public:
      int chg;
      zjy(int n);
      zjy();
      ~zjy();
      zjy(zjy&obj);
      };
      zjy::zjy()
      {
      cout<<"无参构造"<<endl;
      }
      zjy::zjy(zjy &obj)
      {
      cout<<"拷贝构造函数"<<endl;
      }

      zjy::~zjy()
      {
      cout<<"析构函数"<<endl;
      }


      zjy::zjy(int n)
      {
      chg=520;
      n=chg;
      cout<<n<<endl;
      cout<<"带参构造函数"<<endl;
      }

      zjy func()
      {
      zjy obj;
      return obj;
      }


      int main()
      {
      func();
      zjy obj(0);
      zjy chg=func();
      system("pause");
      return 0;
      }

      第二个代码运行结果:

      image-20221201151814859

      • 无参构造:func里面的obj
      • 析构函数:函数调用完会释放内存,这里释放的是第一个obj,所以调用析构函数
      • 带参构造:43行代码
      • 无参构造:是因为用了chg来接收

      由于上面结果不一致,重点参考下面的

      image-20221201152314605

      • 无参构造:调用test_func_2(),从主调函数,进入被调函数,创建Monster obj采用的是无参构造
      • 拷贝构造1号:因为需要函数返回obj,但是函数里面的数据在函数完成时,会被释放,所以采用拷贝构造创建的副本obj
      • 析构(1):当函数完成时,释放内存,调用析构函数释放原本的obj
      • 析构(2):由于没有接收obj,所以会在执行完76行释放返回的obj副本
      • 无参构造:78行调用函数(如上的无参构造)
      • 拷贝构造1号:如上
      • 析构(3):如上,第一个析构
      • 析构(4):这里的析构和第二个析构不一样,这里的析构是因为,main完成了,释放monster接收的obj
    • 问题1:为什么第78行Monster monster=test_func_2()这里没有拷贝构造?

      • 没有东西去接收复制体时,系统会创建一个临时的对象,再用拷贝构造,将返回的obj,拷贝构造给临时变量
      • 由于78行,有一个monster接收返回的obj,系统优化,直接复制给monster,所以不会调用拷贝构造
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      zjy func()
      {
      return zjy();
      }


      int main()
      {
      func();

      system("pause");
      return 0;
      }

      运行结果:

      image-20221201154807685

      • 无参构造:因为这里在return 后面创建了一个zjy(匿名对象),相当于在函数外边创建了一个对象,这里不会采用拷贝构造,所以时无参构造
      • 析构函数:因为没有接收对象,所以在49行的时候析构掉了
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      zjy func()
      {
      return zjy();
      }


      int main()
      {
      //func();
      zjy chg=func();
      system("pause");
      return 0;
      }

      运行结果:

      image-20221201155016536

      • 无参构造:因为调用test_func_2(),创建了一个匿名对象,采用无参构造(和上面的无参构造一样)
      • 析构:因为main函数结束,调用析构函数
  5. 对于指针的构造:不能直接将指针指向那个地址,而是,创建一个新的内存用于存放原有的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    int main()
    {
    int *p=new int[5];
    int *q=new int[5];
    for(int i=0;i<5;i++)
    {
    p[i]=i;//可以相当于创建了一个数组,对于数组的存储可以用arr[i]=int类型

    }
    for(int i=0;i<5;i++)
    {
    q[i]=p[i];
    }
    for(int i=0;i<5;i++)
    {
    cout<<q[i]<<"\t";
    }
    system("pause");
    return 0;
    }
  6. 浅拷贝和深拷贝

    image-20221202094645975

  7. 如何防止默认拷贝的发生(浅拷贝)?

    image-20221202095003679


函数
https://tsy244.github.io/2023/03/26/cpp/函数/
Author
August Rosenberg
Posted on
March 26, 2023
Licensed under