您的位置:首页 > 编程语言 > C语言/C++

C++Primer学习笔记------对象和类(2)

2014-09-29 15:56 197 查看
一般来说,当我们创建一个类的时候,这个类的数据成员都应该封装在私有部分,这成为数据隐藏,是不允许在类的外部进行改变的,只能在成员函数的内部来进行访问。我们会想到,每一次定义一个对象的时候,都自己实现一个初始化的类成员函数然后自己写代码来调用它达到初始化的地步,但是,不能强迫所有人这么做,并且很有可能会忘记,所以我们要想一种自动的办法来为类对象进行初始化。

一、构造函数

首先,构造函数也是一种函数,但是这种函数有以下几种特殊的地方

1、该函数没有返回类型

2、构造函数的名字要求和类名一样。

3、如果没有定义构造函数,编译器也会自动为程序生成一个没有任何参数的默认的构造函数。一旦你自己定义了一个构造函数,无论是由参数还是没有参数,那么编译器都不会在为你指定任何的默认构造函数了。

二、使用构造函数

使用构造函数分为两种形式,一种是显示调用,另外一种是隐式调用,构造函数还可以与new一起来使用。

例如

stock food = stock(1,2,3)

stock food(1,2,3)

stock food = new stock(1,2,3)

这三种方式都可以在创建类对象的时候自动调用类的构造函数来初始化类对象。

以前我们可能看见这样的调用,stock food;这个时候,如果我们 没有定义任何的构造函数,那么这时编译器就会为我们生成一个默认的构造函数,如果此时我们已经定义了一个带参数的构造函数的时候,因为编译器不能再为我们指定,而且我们自己没有定义不带参数的构造函数,所以,此时这样的调用就会出错。

另外,默认的构造函数一般是没有任何参数的,即使是有参数也要为所有的参数都提供默认值。

定义一个默认的构造函数有两种方式,第一种是在定义的时候,为参数列表中该对象的需要初始化的成员都提供默认值,第二种就是通过重载没有参数的构造函数来重新定义。无论定义了几个构造函数,但是默认形式的只能有一个。

三、析构函数

有构造函数,也就是创建对象并且初始化的函数,那么就得有删除对象,回收他所占用内存的函数。这个函数叫做析构函数。如果在构造函数里面用了new来分配内存的话,那么就得用delete来进行释放内存。如果构造函数里面没有new的影子,那么析构函数里面就什么都不用写即可。他和构造函数一样,如果我们自己没有定义的话,会为我们生成一个默认的析构函数,这个函数什么都 不做。

析构函数基本和构造函数的形式差不多,但是也有他需要注意的两点。

1、析构函数就是在构造函数前面加一个~符号,就变成了析构函数。

2、析构函数是不能接受任何参数的,所以析构函数的函数头部的声明形式是确定的

析构函数一般来说都是自动被调用的,很少有显式调用构造函数的。

四、const成员函数

如果在定义一个对象的时候,我们定义了一个const对象,那么就证明这个对象是不能够被修改的。此时当我们在去利用这个对象调用一个成员函数的时候编译器会报错,因为不敢保证我们的const对象在这个成员函数中不背修改。

想使用const对象去调用函数,那么这个函数也必须是const的,所以,在函数定义的时候可以在函数参数列表后面加上const关键字,其实只要这个类方法不会修改对象,那么我们就应该把这个方法声明为const,这样会更加符合标准。

五、this指针

this指针指向的是调用某一个成员方法的对象,每个成员函数在调用的时候,都会隐式的把调用这个函数的对象的地址传递给this指针。

六、对象数组

可以像创建普通数组那样的创建对象数组,只不过把原来的普通的数据类型处换为类名。

在对对象数组内部的元素进行初始化的时候,可以根据给普通数组初始化的形式,只不过大括号内,利用逗号隔开的每一个值都是需要调用相应的构造函数来完成的。如果只是初始化了一部分对象数组中的元素,那么其余的没有初始化的,编译器会自动调用默认的构造函数去初始化他们。

初始化一个对象数组有以下步骤,首先,在定义这个对象数组的同时就会调用默认的构造函数去创建对象,然后,根据括号中调用的构造函数,创建临时对象,然后把他们赋值给对象数组中的元素,所以要使用对象数组,则必须要有默认的构造函数才行,不管这个默认的构造函数是你自己定义的,还是编译器自动为你创建的。

七、类的作用域

前面有说到变量和函数都有作用域,那么同时,类也会有作用域存在。类的作用域就是类定义开始,一直到类定义结束这期间都是类的作用域。也就是说,在这段范围内定义的名称,在类的外部是不可见的,不同的类在自己的作用域内,可以使用相同的名称但不会相互影响。类的作用域还有一个作用就是,不能从类的外部去访问类的内部的成员,即使是类中的公有部分也不例外,调用公有部分的成员,也是需要通过对象来调用。并且在定义类中成员的时候,虽然可以拿到类的外部来定义,但是和普通的定义不同,是必须加上作用域标识符的,
标识这个成员是属于一个特定的类的。但是如果是在类的成员函数内部调用其他的类成员的时候,则不用加上作用域标识符,因为类中的成员都是互相可见的。

我们 通常想在类的作用域内定义一个符号常量,以便对所有的对象都能实现共享,但是这在C++中是不允许的,因为类的声明中只是对创建类的对象的一个描述,并没有 任何空间去装下类对象的某一个成员,定义符号常量利用const int temp = 3;这样的形式,这势必会在内存中要开辟一段空间才可以。

为了解决这个问题,可以通过我们可以在类的声明部分声明一个枚举。 在类的声明中声明一个没有名称的枚举类型变量是不会创建类的数据成员的。

还有一种办法,就是吧这个我想要定义的符号常量前面加上static,这样一来这个符号常量就不会存在于对象中了,它是单独的存储在内存的静态存储区内,这样在类的声明过程中不算是创建了数据类型的成员,仅仅是作用域为类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息