咸鱼的翻身计划5:C++中的类和对象,对象特性

1.构造函数和析构函数

当你创建一个类时,如果你不自己定义,编译器会默认创建这两个函数,并且会自动调用,但他俩就是空实现,也就是说函数里木有内容。

构造函数是在创建一个对象时自动调用对成员属性进行初始化,析构函数则是将其在对象销毁前自动调用来进行一些清理工作。

语法        

构造函数:类名(){  }                        

没有返回值,跟void差不多,可以有参数,因此可以重载,会自动调用,而且只会调用一次。

析构函数:~类名(){  } 

没有返回值,跟void差不多,不可以有参数,因此不可以重载,会自动调用,而且只会调用一次。

所以说啥叫自动调用呢,比如你定义了一个名叫 student的类,然后你是不是实例化也就是定义一个对象 像这样:student  s;创建了一个student类的对象s,这个时候构造函数就已经被调用了,但没啥反应,因为这时候因为你木有在student类内定义这个函数,系统默认创建了构造函数student(){这里面啥也木有},它是一个空函数。

2.构造函数的分类和调用

按类型分为普通和拷贝,按参数分为有参和无参

class student{
public:
    student()    //无参构造又叫默认函数    因为如果你不写,系统会默认生成这个函数
    {
         
    }

    student(int age)    //有参构造函,数普通构造
    {
         m_Age = age;
    }

    student(const student &s)有参构造函数,拷贝函数 加const修饰,表示不能改变传进来的引用    
    {
         m_Age = s.m_Age;
    }

    int m_Age;
};

int main()
{
    //调用
    //括号法
    student s1;       //调用了默认构造函数

    student s2(18);    //调用了有参构造函数

    student s3(s2);    //调用了拷贝构造函数

    //显示法

    student s4 = student(19);

    student s5 = student(s4);    //调用了拷贝构造函数

//    student(10); 这种叫匿名对象,当前行结束后系统会立即回收匿名对象。

    //隐式转换法
    student s6 = 10;    //调用了有参构造函数,相当于  student s6 = student(10);
   

    student s7 = s6;    //调用了拷贝构造函数


    return 0;
}

目前先明白代码是啥意思,能看懂代码,等到时候才能拿来就用,学习后面的知识的时候也更轻松。

构造函数就是一个给类的属性初始化的函数,也只有类可以这样调用 用来初始化变量的函数

析构函数有点像free,delete 的用法,主要是用来释放你定义的类时所申请只占用的空间。

3.拷贝构造函数的调用时机,这里我不再具体写代码了,借用上面写的。

1.当我们已经定义并初始化了一个对象,要初始化另一个新对象时,会调用拷贝构造函数

 比如 :   student s2(18);    //调用了有参构造函数        

                student s3(s2);    //调用了拷贝构造函数让s1,s2属性值完全一样。

2.将类作为一个函数的值传递的时候,也会调用到拷贝构造函数,

 比如 :函数 void test(student s){ s.m_Age = 0 };        sudent s1(10);     test(s1);   

这是一个正常的函数的值传递调用,只不过传递的值得类型是studen类,此时s是形参,相当于,实参s1将他的值了拷贝一份传递给了形参s。所以调用到了拷贝函数,编译器自动调用的。众所周知值传递形参不会改变实参,所以调用函数后,s1.m_Age的值还是10。

正常情况下,c++编译器会默认给一个类至少提供三个函数,默认构造函数(空实现),析构函数(空实现),拷贝构造函数(提供简单的赋值操作)这样保证了你用类作为值传递给函数的时候可以实现。

 如果你自己定义了拷贝构造函数,系统就不会再给你提供默认构造函数。先晓得有这种情况就行,知道了好像也没啥用这会儿。

浅拷贝&深拷贝,析构用途

简单的进行赋值操作的叫浅拷贝,编译器默认提供的拷贝构造函数就是浅拷贝,
深拷贝则需要用到new关键字,向堆区申请空间,进行赋值操作,这就叫深拷贝,这得你自己个写,系统提供得是最简单的,有时候无法提供你想要的一些功能。

class student{
public:

    int m_Age;
    int *m_Height;    //这是个指针变量


//浅拷贝函数,如果你不写,编译器会提供的就是这种,稍微带点智能,你有几个属性他就会有几个赋值操作。    
    
    student(const student &s)
    {
         m_Age = s.m_Age;

         m_Height = s.m_Height;

         //这里因为是赋值操作,俩指针会指向同一块内存,也就是存的地址一样
         //这样在析构函数到用时,会delete两次同一块地址,不合法,也是浅拷贝的弊端       
                       
    }


//深拷贝构造函数,当然如果是你自己定义的函数,你还可以加一些cout啥的,当成void来用,但最好不要偏离实现初始化的功能。
//这跟上面的函数重名,他俩又没构成重载,运行会报错,所以正常只能有一个拷贝构造函数
   
    student(const student &s)
    {
        
         m_Age = s.m_Age;

         m_Height = new int(*s.m_Height);   //这相当于重新申请了一块新空间给指针,
                                            //所以不会出现浅拷贝出现的问题

    }


//析构函数,没定义之前系统会默认提供的是个空的,在对象定义后,运行结束前会自动调用。

    ~student()
    {
        delete(m_Height); //因为你如果要给指针变量赋值就要申请一块空间;m_Height=new int(180)
                          //这时候用完,也就是在代码结束前要释放申请的空间。
    }

};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值