一个基本问题引出的话题,类常识你知多少?

 

     以前觉得吧,写文章纯属浪费时间,有那么点时间还不如玩会游戏、和姑娘聊聊天。现在这觉得,写写读书笔记也是好的,一来信息分享,(各个云平台不就是分享、然后大数据么)二来温故而知新,加深了对知识的理解。话不多说,继续写

    问题:在C++中一个空类,他会产生多少个函数呢?

    答案还是慢慢揭晓,首先介绍C++几个成员函数。

    构造函数:

    什么是构造函数?构造函数的作用又是什么?可以有多少个构造函数?

    首先,构造函数是类中一种特殊的成员函数,它和类是同名的、没有返回值。构造函数的作用是什么?我个人觉得他主要是用来提供类的各种初始化。

    刚刚我讲到了各种初始化,想必大家也就知道了构造函数是可以多个的。

    在我们没有显示的定义构造函数的时候,编译器会自动生成一个构造函数,这个构造函数是不带参数的;当然,如果我们已经在类中显示的定义了若干或者一个构造函数,那么编译器就不会生成一个构造函数了。比如有一个类Class A;

1 class A{
2 public:
3      A(int a){
4         b=a;
5         cout<<b;
6     }
7 private:
8     int b;
9 };

     在这个类中,我定义了一个带有一个整形参数的构造函数,这就意味着如果我们要New一个新的对象只能传递一个int参数。如果不传递参数就会报错,这也间接说明了,定义了构造函数就不会参数默认构造函数了。

    所以,如果我们需要一个无参数的构造函数,就必须显示的定义。一般来说,定义了一个带参数的构造函数就要定义无参数的构造函数,这主要从安全和方便的角度来考虑的。因为我们经常是A x=new A();如果没有定义无参数构造函数,我们可能连错在哪里都不知道。

   这里说到了构造函数的主要功能是初始化成员数据。上面已经提供了一种初始化方式,还有一种初始化方式是class A:b(5){};

   需要注意的是在C++成员变量的初始化顺序是按照声明的顺序保持一致的。而以构造函数的初始化顺序无关。

 

   一种特殊的构造函数:复制构造函数

   注意,这里是复制,而不是赋值。

   复制构造函数其实就是对象的拷贝过程。例子如下。

1      A(const A &other){
2          this->b=other.b;
3          cout<<this->b;
4      }

   还有一种是赋值。下面即是。其中x赋值到m。

1 A x(6),m=x;

  谈到复制构造函数的话,有必要强调一下深复制和浅复制的概念。也称为深拷贝、浅拷贝

   先澄清我这里的两个概念,如果对象A复制到B,则称A为原对象,B为新对象。

   浅复制是指新对象所有变量都含有原对象的值,但是引用仍然指向原对象。

   深复制是指新对象所有的变量都含原有对象的值,并且所有的引用也进行了复制。

   这个怎么理解呢?其实就是浅复制之后,引用还是对原对象的(所以一旦原对象指针释放,新对象的指针就不知道指向何处了,野孩子就是这样出现的)。而深复制,把引用也复制了(创建了自己的资源,原对象再折腾也影响不到我)。具体例子见下面。

 1 struct Test{
 2     char *ptr;
 3 };
 4 void shallow_copy(Test &dest,const Test &source){//浅复制
 5     dest.ptr=source.ptr;
 6 }
 7 void deep_copy(Test &dest,const Test &source){//深复制
 8     dest.ptr=(char*)malloc(strlen(source.ptr)+1);
 9     memcpy(dest.ptr,source.ptr,strlen(source.ptr)+1);
10 }

    浅拷贝很容易造成程序崩溃,比如说原对象中有动态指针,如果浅拷贝,那么新对象指向的还是原对象的指针,如果原对象释放掉了.那么新对象指向哪里??

    更多这方面的知识请查阅相关文章。

    析构函数

    与构造函数相对的是构造函数,构造函数是初始化对象成员,那么析构函数就是释放资源的,一般析构函数都是最后退出的时候执行的。

    定义的话类似构造函数,在构造函数加一个~,比如~A(){};

    另外析构函数无参数,无返回值,也只能有一个析构函数。

    在继承中,比如son类继承parent类,son littleson;这个过程是先调用父类parent的构造函数,再调用son类的构造函数;析构函数则是一个相反的过程,先调用子类的析构函数,再调用父类的析构函数。其实这个我们从资源的分配和回收角度很容易理解。

    

    谈到资源的分配,我们知道编译器自动分配是在栈中进行,程序员申请资源和释放资源是在堆中进行的。

    在C++中资源的申请有两种不同的方式,New,malloc,想对应的释放也有两种方式delete,free.我们分析一下这两种方式的异同。

    相同的我们就不多说了,都可以进行资源的动态申请是他们最大的相同之处了,那么异呢?

    1、malloc是调用函数,而new 是运算符

     2、malloc需要计算申请的字节数,并转化成相应类型;而new则是自动计算的。

     3、malloc是不安全的,而New是安全的(申请的时候不会出现编译出错)如:int p=(int)malloc(sizeof(double));

    4、maolloc需要库文件的支持,函数肯定需要呀,而new 不需要,因为人家是运算符啊,你想想+须有库文件就知道了嘛。

     5、new会调用构造函数,delete调用析构函数。

   那么似乎new比malloc牛b多了,我们就不需要malloc了呢?

   malloc是一种旧式的资源申请模式,现在都提倡new申请这是无疑的。但是有一种情况用malloc会取得比较好的效果,就是当程序在一次申请之后,可能会使用完毕需要再次申请的时候,因为有realloc啊。当然也可以用vector.

    

    现在可以回答最开始的问题了,它会产生的成员函数至少包括:构造函数,析构函数,复制构造函数,取址运算符重载函数,赋值运算符重载函数,const取址运算符重载函数。

     版权所有,欢迎转载,但是转载请注明出处:潇一

 

原文地址:https://www.cnblogs.com/xiaoyi115/p/3626040.html