C++类之构造器和析构器

来源:互联网 发布:云计算机房维护 编辑:程序博客网 时间:2024/05/21 09:57

虽然平时我们都叫构造函数和析构函数,但他们并不像真正的函数一样,不管是构造还是析构两个都没有返回值,所以最好称他们为构造器和析构器。基础就不说了,下面分别说一下这两个东西中容易被忽视的东西:

一、构造器
1.我们知道构造器若没有定义,编译器会自动生成一个默认无参的构造器,一旦自定义了构造器,那么就不再会有自动生成,一般情况下最好自定义中带有无参的构造器,不然bug是不可避免的,建议是定义带默认参数的构造器,例如:

class A{private:    char* a;public:    A(int len = 10){            a = new char[len];    }   };

上面列举了一个简单的带默认参数的构造器的例子,这样在创建对象时,可以不带参数也可以带一个参数,想带多个参数的情况类似。显然构造器必须放在public下,不然怎么创建对象。
构造器的重点在于它的目的是初始化对象,那么是如何分配空间的呢?
首先先创建一个对象,如下:

A *p = new A;

一newA就创建一个A类的对象,p指向这个对象的首地址,也就是说类A中char* a的地址,这时候给对象一个4字节的地址空间(指针在32位下是4个字节),然后在构造器中又给a了一个长度为len的内存空间,其形象的表示如下图:
这里写图片描述
根据上面的说明,显然构造器并不只是开辟了C2这么一个对象的内存空间,同样也为a开辟了空间,是一连串的效应。
刚才也说过了,如果自定义了构造器,那么编译器就不会自动生成无参的构造器,这时候如果没有定义无参构造器,那么当创建对象数组时,若没有初始化,就会报错。

class B{private:    string s;public:    B(string str): s(str){}};int main{    B b[5];    B c[2] = {B("acd"), B("dasf")};}

这种完全不初始化,或者不完全初始化都会报错。
把B类的构造器改成这样:

class B{private:    string s;public:    B(string str = ""): s(str){}};int main{    B b[5];    B c[2] = {B("acd"), B("dasf")};}

就没错了。

所以强烈推荐使用带默认参数的构造器。

二、析构器
析构器与构造器的作用相反,是用来释放对象的。构造器先开辟C2,再开辟C3,而析构器则先释放C3,再释放C2:跟上面对应,释放如下:

delete p;

再小结一下什么时候才会调用析构器:
1、当对象所在的作用域结束的时候,也就是说达到所在作用域的“}”符号的时候。
2、当用delete语句释放对象的时候。

0 0
原创粉丝点击