C++的构造和析构函数

一、构造函数

  1、构造函数是在创建对象时自动调用的对象,在整个对象的生命周期里,一定会被调用一次且只能被调用一次(不包括被强制调用)。

  2、在构造函数中可以负责对成员变量的初始化、分配资源、设置对象的初始状态。

  3、构造函数可以有多个版本,这些不同的版本之间会构造重载,创建对象时的方式不同、给的参数不同会调用相应的构造函数,如果调用的构造函数不存在可能会造成编译错误。

  4、如果类中没有定义构造函数,编译器会自动生成一个无参的构造函数,当自定义了一个其他版本的构造函数,则系统默认的无参函数就不会再生成。但是为了防止无参方式创建对象时出错,建议设置2个构造函数。

  5、无参构造未必无参,在C++中函数可以有默认参数,如果有参构造全部设置了默认参数,就会和无参构造有冲突,他们2个只能有一个存在。

  6、拷贝构造函数是一种特殊的构造函数,就是用一个已有的对象去构造其同类的副本对象,就是对象克隆。

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

class Student
{

    char name[20];
    char sex;
    short age;
public:
    Student (const char* _name,char _sex,short _age)
    {
        if(strlen(_name)<20)
        {
            strcpy(name,_name);
        }
        sex = _sex;
        age = _age;
    }
    Student(Student& that)
    {
        strcpy(name,that.name);
        sex = that.sex;
        age = that.age;
        cout << "我被调用了" <<endl;
    }
    void show(void)
    {
        cout <<name <<" "<<sex <<" "<< age<<endl;    
    }
};
int main()
{
    Student stu1("hehe",'m',17);
    Student stu2 =stu1;
    stu2.show();
}

  7、同样的,编译器也会默认生成一个拷贝构造函数,编译生成的拷贝构造函数默认会逐字节的复制类中的每一个成员。如果在类A中有类B的成员,那么在类A的拷贝构造函数中会自动调用类B的拷贝构造函数。

  8、程序员可以自定义拷贝构造来取代默认的拷贝构造,一旦自定义拷贝构造函数,那么编译器就不再生成,并且拷贝构造函数和构造函数不同的是,拷贝构造是只能有一个的,不能重载。

  9、一般情况下编译器生成的拷贝构造完全是够用的,不需要自定义拷贝构造函数。

  10、赋值构造函数就是一个对象给另一个对象赋值的时候调用的函数,与拷贝构造不同的是,对象A和B都是已经构造完成 的,此时要做的是讲B =A;而拷贝构造是需要对象A去创建对象B的。

#include <iostream>
#include <string.h>

using namespace std;

class Student
{
    char* name;
    char sex;
        short age;
public:
    Student(const char* _name="",char sex='f',short age=1):sex(sex),age(age)
    {
        name = new char[strlen(_name)+1];
        strcpy(name,_name);
    }
    
    Student(const Student& that)
    {
        name = new char[strlen(that.name)+1];
        strcpy(name,that.name);
        sex = that.sex;
        age = that.age;
    }

    

    void show(void)
    {
        cout << name << " " << age << endl;
    }

    void addAge(void) const
    {
        age++;
    }

    void operator = (Student& that)
    {
        if(this == &that) return;
        delete[] name;
        name = new char[strlen(that.name)+1];
        
        strcpy(name,that.name);
        sex = that.sex;
        age = that.age;
        
    }

    ~Student(void)
    {
        delete[] name;
    }
};

int main()
{
    Student s1("lili",'m',33);
    s1.show();
    Student s2 = s1;
    s2.show();
    s2.addAge();
    s2.show();
    s2 = s1;
    s2.show();
}         

  11、同样的编译器也会默认生成赋值构造函数,一般情况下默认的赋值构造也是基本够用的,除非有成员是指针,指向了额外的内存空间,这种情况我们才需要自定义拷贝构造函数和赋值构造函数。

二、析构函数
   1、当对象被销毁时自动调用的函数叫析构函数,对象的整个生命周期中只能被调用一次,它是对象被销毁前的最后一个执行的动作。
     class 类名
     {  
      // 不能重载、只能有一个
     ///没有返回值、没有参数 
      ~类名(void)
      {
   
      }
     }
   2、编译器会默认产生一个析构函数,默认析构函数负责销毁能看的到的成员,如果有成员是类,会自动调用成员的析构函数,成员的析构过程与构行过程相反。
   3、析构函数虽然不能与重载,但可以自定义,有自定义析构函数默认析构就不会生成。
   4、当类中有析构造函数看不到的资源时(new/malloc)、有需要还愿的设置时(把打开的文件关闭/把获取到的数据保存),这时就需要自定义析构函数。


 

    

猜你喜欢

转载自www.cnblogs.com/yyc954330712/p/9445432.html