zoukankan      html  css  js  c++  java
  • C++(二十六) — 构造函数、析构函数、对象数组、复制构造函数

    1、构造函数

    (1)每个类都要定义它自己的构造函数和析构函数,是类的成员函数。

      特点:名称与类名相同;没有返回值;一定是共有函数,可以直接访问类内所有成员函数;可以带默认形参,可以重载;

    class clock
    {
    public:
        // 无参构造函数
        clock()
        {
            cout << "无参构造函数" << endl;
        }
        // 有参构造函数
        clock(int h, int m , int s)
        {
            hour = h;
            minute = m;
            second = s;
            cout << "有参构造函数" << endl;
        }
        //// 有默认参数值的有参构造函数
        //clock(int h=8, int m=20, int s=20)
        //{
        //    hour = h;
        //    minute = m;
        //    second = s;
        //    cout << "有默认参数值的有参构造函数" << endl;
        //}
        //拷贝构造函数完成,用一个对象初始化另一个对象
        clock(const clock &t) // const 加不加都可以
        {
            cout << "复制构造函数" << endl;
        }
    
    private:
        int hour; int minute; int second;
    };
    
    void main()
    {
        clock myclock;  // 调用无参构造函数,不能加括号
        //clock myclock_1();// 调用有参构造函数,此时会出错,因为没有传参数
        clock myclock_2(8,20,20);// 有参构造函数,必须要写上参数
    
        clock myclock_3(myclock_2);// 调用复制构造函数
      clock myclock_3 = myclock_2;// 同样调用copy构造函数
    system("pause"); }

    (2)注意:

      (1)类中没有定义任何构造函数时,才使用默认构造函数,只要定义了,就不会存在默认构造函数;

      (2)不能同时出现无参构造函数和带有全部默认参数值的构造函数;二者只能出现一个;

      (3)复制构造函数,使用一个已存在的对象,初始化一个新的同类对象。如果未定义,系统将会自动生成;但是,如果申请动态空间(堆空间),则必须定义。

      (4)构造函数中调用构造函数,是危险的行为。(会因为调用匿名对象,而直接析构掉)

     2、对象数组

      解释为什么需要构造函数,在定义对象数组时,自动初始化。

    class student
    {
    public:
        student(int, char*);
        student();
        ~student();
        void set(int i, char* c);
        void printstu()
        {
            cout << "id: " << id << "   name: " << name << setw(5) << endl;
        }
    private:
        int id;
        string name;
    };
    student::student()
    {
        cout << "默认无参构造函数" << endl;
    }
    student::student(int i, char* c)
    {
        id = i;
        name = c;
        cout << "有参构造函数" << endl;
    }
    student::~student()
    {
        cout << "析构函数" << endl;
    }
    
    void student::set(int i, char* c)
    {
        id = i;
        name = c;
    }
    
    void main()
    {
        // 对象数组
        student stu[5] = {
            student(1,"li"),
            student(2,"wang")
        };
        stu[2].set(3, "zhao");
        system("pause");
    }

      定义两个构造函数,此时定义对象数组时,可以不用初始化。

      构造函数在定义对象时调用,析构函数在程序结束时调用,而且,析构顺序与构造顺序相反。

    3、复制构造函数 

      复制构造函数,也是构造函数。只在初始化时调用,如果定义对象后赋值,比如,t1=t2,则只是运算符重载,没有调用构造函数。

    student::student(student &s)
    {
        cout << "复制构造函数" << endl;
        id = s.id;
        // 使用字符指针定义的变量,需要定义复制构造函数,申请空间。
        // 也需要定义 构造函数 和 析构函数
        name = new char[strlen(s.name) + 1];
        if (name != 0)
            strcpy_s(name, strlen(s.name) + 1, s.name);
    }

      调用:有四种方法。

        // 对象数组
        student stu[5] = {
            student(1,"li"),
            student(2,"wang")
        };
        stu[2].set(3, "zhao");
    1、 student stucopy(stu[
    0]);
    2、 student stucopy_1
    = stu[0];

      还可以用函数调用:

    void f(student p)
    {
        // 用于类对象的复制。
        cout << "此处要调用复制构造函数" << endl;
    }
    
    student stu;
    stu.set(3, "zhao");
    f(stu);

      还有一种情况:就是函数返回值是一个类对象,返回的是一个新的匿名对象,此处要调用复制构造函数。

    student g()
    {
        student stu1(1, "abc");
        return stu1;
        // 用于类对象的复制。返回的匿名对象的复制,因为 stu1 是局部变量,函数结束时要销毁。
        cout << "此处要调用复制构造函数" << endl;
    }
    student s = g();//此处只是换了名字,没有调用复制构造函数了

      如果匿名对象,初始化另一个同类型的对象,则匿名对象转成有名对象,不调用复制构造函数;

      如果匿名对象赋值给另一个对象,则匿名对象马上被析构;

    4、匿名对象的声明周期

    int run3()
    {
        cout << "run3 start...." << endl;
        B(1, 2);  //执行此步,匿名对象调用构造函数后,马上调用析构函数(因为没有东西接)
    
        //此处,匿名函数被 b 接到了,就只调用了构造函数,匿名对象转成有名对象
        // 该有名对象是局部变量,在函数结束返回时析构(也就是 return 处)。
        B b = B(1, 2);
    
        cout << "run3 end...." << endl;
        return 0;
    }
  • 相关阅读:
    ZOJ 3332 Strange Country II
    ZOJ 3331 Process the Tasks(双塔DP)
    ZOJ 3326 An Awful Problem(模拟)
    HDU 1796 How many integers can you find(容斥原理)
    HDU 4059 The Boss on Mars(容斥原理)
    HDU 4135 Co-prime(容斥原理)
    HDU 5677 ztr loves substring(回文串加多重背包)
    CodeForces 668B Little Artem and Dance
    CodeForces 667A Pouring Rain
    Java实现 LeetCode 764 最大加号标志(暴力递推)
  • 原文地址:https://www.cnblogs.com/eilearn/p/10187149.html
Copyright © 2011-2022 走看看