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;
    }
  • 相关阅读:
    许可和授权的研究及其破解
    Citect:How do I translate Citect error messages?
    异步IO模型和Overlapped结构
    SanDisk SecureAccess™ Software
    Asynchronous socket communication
    一种字节转字符串的语法
    【转载】C# Tutorial
    保存项目文件“XXX.csprj”时出错。类没有注册。
    markdown中的注释
    ubuntu上nginx详细安装部署教程
  • 原文地址:https://www.cnblogs.com/eilearn/p/10187149.html
Copyright © 2011-2022 走看看