C++编程思想--初始化与清除

来源:互联网 发布:mysql 两个表的合集 编辑:程序博客网 时间:2024/06/04 17:48

初始化与清除

安全性包括初始化与清除。其实就是构造函数与析构函数的作用。对于一个库的struct来说必要的清除工作容易遗忘。初始化和清除的概念是简化库的关键。减少客户程序员去为完成这些操作引起的细微错误。比如说内存忘记释放等等。

1)如何进行初始化使用构造函数保证每个对象被初始化,编译器在创建函数自动调用构造函数,在使用对象之前完成。它指定对象如何创建或者设定对象的初始值,构造函数的参数保证对象的所有部分都被初始化成合适的值。因此编译器必须知道构造函数的名字,那么就不能与其它的成员函数冲突。传递到构造函数的第一个参数为this指针。它是没有返回值,为什么呢?若是有返回值,要么编译器就必须知道怎样的处理返回值,要么客户程序员自己来显示的调用构造函数,这般安全性就失去了。

2)析构函数用来处理清除,在库中,对象可能会分配了内存,修改了硬件参数,或在屏幕上显示一些字符。忘记清除,将不会消失,会影响到其他的代码或者程序。

值得注意的是析构函数是在对象的作用域的右括号处被调用。

有的时候我们会忘记曾经创建某个对象,为了保障安全性,尽量减少在块中的生命周期,减少变量在块中的其它地方被误用的机会。尽管我们将定义放在函数的前面,编译器在开始就可以分配空间,但是对于我们程序原来说,效率是一样的,况且编译器会检查没有把一个对象的定义放在一个块中。比如在if语句中定义一个变量,在if外面使用这个变量,编译器会报错,同样的情况会出现在switch中,所以在switch中应该尽量的用括号的将块中的函数括起来

如下:

#include "C06 Nojump.h"X::X(){}void f(int i){X x1;//将x1放在if之后会可能直接的跳过。所以必须放在函数头if (i<10){goto jump1;//当i>=10时,这条语句会跳过,于是出现jump1会初始化}jump1:switch(i){case  1://这里若没有{},会出现x2的初始操作跳过由“case”标签跳过的错误。所以应该加上括弧{X x2;    break;}case 2:{X x3;    break;}}}int main(){f(9);f(11);}

下面我们将默认的构造函数,在结构或者类中,没有显示定义构造函数,编译器会自动创建一个。但是我们如果寄希望于这个函数可以将对象的内存清零,这是不可能的。如此不仅会造成额外的负担,且会使程序员难以控制程序。于是我们明确的定义构造函数就显得非常的必要。

    3重载的构造函数。有的时候我们可能会需要将构造函数进行重载。重载可以对程序有着良好的兼容性,比如之前的程序需要改变,可以在不修改原来代码的基础上,添加代码。如此增加灵活性。

函数重载.,重载可以是参数类型不同、参数个数不同,但是返回值不同不能作为重载的条件,因为在C中是可能忽略返回值的,也就是函数的副作用。在这种情况下,编译器不能判断到底调用哪个函数。

实现方式:编译器将会用不同的参数类型来修饰不同的函数名,比如下面的函数:

Void print ( char);

Void prtint  (float)

.对应的编译器可能会产生类似于_print_char_print_float的内部名。不同的编译器会不同。但是都会修饰这些名字、范围和参数来产生内部名以供它和链接器使用。这样的名字修饰就提供了一个安全网。也就是类型安全连接。若参数类型为char,但是传进去一个int类型的,其实编译器将函数修饰为f_cha,而f_int不能够找到,于是出现错误,

    4)默认参数:函数的重载就是要实现同一个函数名可能有多个不同的处理,根据参数的个数或者是类型来判断,那么默认的参数呢。有的时候使用默认参数也可以达到同样的效果。使用默认参数的函数

(1)默认参数只能放在函数的声明中,通常放在一个头文件中。

(2)而且默认值只能在参数列表的后面

(3)一旦在一个函数调用中开始使用默认参数,这个参数后面的所有参数都必须是默认的。

   5)使用默认参数与函数重载:

 (1)当函数的许多参数都有特定值的时候,或者一个函数使用了一段时间,需要在现有的一组参数后面再加一些参数,通过将这些新增参数作为默认的参数,可以保证客户代码不受影响。

  (2)不能将默认参数作为一个标志去执行函数的哪一块。因为使用默认值作为标志维护起来非常的不方便。相当于在函数中执行的两段不一样的代码。



原创粉丝点击