C++核心编程(八)构造和析构

构造和析构函数
构造函数:完成对象初始化工作
析构函数:完成对象清理工作
(1)构造函数语法:
1)函数名和类名同
2)函数的参数可以不同,可以重载
3)程序在调用对象的时候会自动构造,无须手动调用,而且只会调用一次
4)构造函数没有返回值也不写void

(2)析构函数语法:
1)析构函数,没有返回值,也不写void
2)函数名称和类名相同,在前面加~
3)析构函数不可以有参数,因此不可以发生重载
4)程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次

注意:先创建的对象后清理
例子:

#include<iostream>
using namespace std;
class test
{

    private:
        int number; 
    public:
    	test(int number)
    {
        this->number=number;
        cout<<"number="<<number<<endl;
  	 }
    	~test()
    {
      	 cout<<"析构成功"<<this->number<<endl;
  	 }
};

void test()
{
    class test t(1);
    class test t1(2);
}
int main()
{
    test();
}
打印结果:number=1
		 number=2
		 析构成功2
		 析构成功1
构造函数的两种分类:
1)按有无参数分:有参构造和无参构造
2)按类型分:普通构造和拷贝构造

三种调用方式:
1)括号法
2)显式法
3)隐式转换法
#include<iostream>
using namespace std;
class person
{
    public:
        person(const person &p)//拷贝构造函数
    {
        this->age=p.age;
        this->sex=p.sex;
    }
        person(int age,int sex)
    {
        this->age=age;
        this->sex=sex;
    }
        void get_age_sex()
    {
            cout<<age<<endl;
            cout<<sex<<endl;
    }
        person()
    {

    }
       
    private:
        int age;
        int sex;
};
void test()//调用
{
    //1.括号法
    person p;//调用默认构造函数时,不要加(),不然编译器会认为在声明一个函数
    person p1(10,2);
    person p2(p1);
    p2.get_age_sex();   

    //显示法
    person x_p;
    person x_p1=person(10,2);
    person x_p2=person(x_p1); 
    //person(10,2)匿名对象,特点:当前行执行结束后,系统会立即回收匿名对象
    //不要利用拷贝构造函数来初始化匿名对象;编译器会认为person(x_p1)==person x_p1,编译器会认为是一个对象的声明
    
    //隐式转换法
    person y_p={10,2};
    person y_p1=y_p;
    //构造函数有多个参数的时候使用{}
}
int main()
{
    test();
  
}
构造函数的使用场景:
1)用已经创建好的对象为另一个对象赋值
2)一个对象在函数中作为形参,且该函数被调用
3)函数中创建的局部对象变量作为返回值为其他对象赋值(编译器不同,可能会优化处理)
	#include<iostream>
using namespace std;
class person
{
public:
    person()
    {
        cout<<"默认构造"<<endl;
    }
    person(int age)
    {
        this->age=age;
        cout<<"赋值构造"<<endl;
    }
    ~person()
    {
        cout<<"析构函数"<<endl;
        cout<<"age="<<age<<endl;
    }
    person(const person &p)
    {
        cout<<"拷贝构造"<<endl;
    }
    int age;
};

void test_one()
{
    //使用已经创建完成的对象来初始化另一个对象
    person one_p(20);
    person one_p1(one_p); //person one_p1=person(one_p);person one_p1=one_p;
}

#define thiree//如果定义了thiree那么就验证 test_thiree
person test_two
(
#ifndef thiree
        person two_p//以值传递的方式给函数参数传值
#endif
    )
{
#ifdef thiree
    person two_p1(20);
    cout<<"two"<<endl;
    return two_p1;
#endif
}
//值返回方式返回局部对象(这里在黑马上说VS使用了拷贝构造,在VScode和Linux虚拟机上使用g++实验出来的结果好像没有使用拷贝构造函数)
//实际上按道理来说是tes_two()中创建了一个局部的对象two_p1,然后将two_p1赋值给thiree_p;按道理来讲是调用了一次赋值构造,一次拷贝构造,2次析构。这里只看到赋值构造和析构分别为一次,应该是编译的问题
//编译器好像优化处理了,让我们只看到初始化赋值,和一个析构,中间应该会有拷贝和其他析构。
person test_thiree()
{
    person thiree_p=test_two();
    cout<<"thiree"<<endl;
    ++thiree_p.age;
    return thiree_p;
}

void test_fuor()
{
    person four_p=test_thiree();
    cout<<"four"<<endl;
}
int main()
{
   // test_one();

#ifndef thiree
    person p;
    test_two(p);
#endif

//test_thiree();
    test_fuor();
}

C++会提供一个默认的:构造函数,拷贝构造函数(值拷贝,拷贝所有属性),析构函数
1)如果我们定义了构造函数,它就不会提供默认的构造函数了,其他的仍然提供。
2)如果我们定义了拷贝构造函数,他就不会提供默认的拷贝构造函数了,其他的仍然提供。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值