对象的初始化和清理

C++中使用构造函数和析构函数来实现对象的初始化和清理

编译器默认会实现这两个函数,但为空实现。

构造函数语法:

//语法:类名(){}
//没有返回值,也没有void
//函数名称和类名相同
//构造函数可以有参数,因此可以发生重载
//程序在调用对象时会自动调用构造函数,且只调用一次

析构函数语法:

//~类名(){}
//没有返回值,也没有void
//函数名称和类名相同
//程序在调用对象时会自动调用构造函数,且只调用一次
//不可以有参数,不可以重载

举例

    //class Person
    {
    public://注意是在public作用域下
    	Person()
        {
        	cout<<"构造函数的调用"<<endl;
        }
        
        ~Person(){
        	cout<<"析构函数的调用"<<endl;
        }
    }

	void test(){
	Person p2;//打印出"构造函数的调用"和"析构函数的调用"
				//局部变量的数据在栈上,test执行完以后会释放这个对象
	}
	int main(){
    	Person p1;//打印出"构造函数的调用"
        test();
    }
    
    

构造函数的分类和调用

按照参数:有参构造和无参构造(默认)

按照类型:普通构造函数和拷贝构造函数

	//有参构造函数
    Person(int a){
    	int age=a;
    }
    
    //拷贝构造函数
    Person(const Person &p){
    //拷贝出一个一摸一样的对象出来,但是不能修改源对象,所以要加const
        age=p.age;//将传入的对象所有属性赋值给新的对象
    }

调用

	void test(){
    //括号法
    	Person p;//调用默认构造函数,注意在调用默认构造函数时,不要加()
        Person p();//会被编译器认为是函数的声明
        
    	Person p1(18);//调用有参构造函数
    	Person p2(p1);//调用拷贝构造函数
        
        //显示法
        Person p3=Person(10);
        Person p4=Person(p3);//=右边为匿名对象,匿名对象的当前行结束后,系统自动回收该对象
    
    
        //不要用拷贝构造函数来初始化匿名对象
    	Person(p4);//编译器:Person(p4)===》Person p4,被认为是对象的声明,报错重定义
    
    	//隐式转换法
        Person p5=10;
        Person p6=p5;
	}
    

拷贝构造函数调用时机

  1. 使用一个已经创建完毕的对象来初始化一个新对象

     //如上
    
  2. 值传递的方式给函数参数传值

     void work(Person p){
     	
     }
     
     void test(){
     	Person p;
         work(p);
     }
    
  3. 值传递方式返回局部对象

     Person work(){
     	Person p2;
         return p2;
     }
     
     void w=test(){
     	Person p1=work();
     }
     
    

拷贝函数调用规则

默认情况下,C++编译器至少给一个类添加:构造、析构、拷贝构造函数

  • 如果自定义了有参构造函数,C++不再提供默认无参构造函数,但会提供默认拷贝构造函数
  • 如果自定义了拷贝构造函数,C++不再提供其他构造函数