本文共 2159 字,大约阅读时间需要 7 分钟。
类由C语言中结构型演变而来,用于定义对象(变量)。定义一个对象,实际上就是定义了多个类型各异的普通变量。如语句Student zhang3, li4, wang5;定义了三个对象,实际上只是定义18个“普通”的变量,其中的3个单精度型变量分别为zhang3.grade、li4.grade和wang5.grade。由此可知,对象与结构型变量类似,但由第二讲可知,对象的成员变量不允许在程序中直接使用,只能通过公开的成员函数访问,这样做可以保证对象的成员变量处于合法的状态(即不会存储非法的数据)。
类中有成员变量,有成员函数,类也成程序的一个组成单位。类中成员可以在程序的什么地方使用?
类是数据类型的一种,与基本数据类型如int的作用相同,“int型可以在程序的什么地方使用”这类问题比较怪异,只能说某个int型变量(具体的存储单元)可以在什么地方使用,毕竟,int型只是抽象(多用于定义变量),与“什么地方”关系不大。
对象的成员的作用域与成员的访问限制相关,当成员为公开(public)时,它的作用域就是对象的作用域。当成员为私有(private)时,不能通过对象访问它。测试程序如下。
#include<stdio.h>
struct Test
{
public:
int i;
private:
int j;
};
Test g_Object;
void func()
{
printf("%d\n",g_Object.i);
g_Object.i= 55;
}
int main()
{
g_Object.i= 23;
Testte;
te.i= 32;
func();
printf("%d,%d\n",te.i, g_Object.i);
return 0;
}
程序运行结果如下:
23
32,55
程序中有两个对象:g_Object和te,它们各自有两个成员变量,程序中有四个普通的整型变量:g_Object.i,g_Object.j、te.i和te.j。可以通过对象访问的成员变量只有g_Object.i,和te.i。g_Object.i的作用域与对象g_Object的相同,te.i的作用域与对象te的相同。
虽然分析了对象成员变量的使用,但实际上正如第二讲所知,对象的成员变量通常定义为private,不能通过对象在程序中使用。成员函数的用法与成员变量的完全相同。
不能通过对象访问其私有成员变量,私有成员变量怎么用呢?
私有成员变量的作用域仅限于“类”中,故称其作用域为类作用域,也就是说只能在类(对象)的成员函数中使用私有成员变量。测试程序如下:
#include<stdio.h>
struct Test
{
public:
void setI(int value)
{
i = value;
}
int getI()
{
return i;
}
private:
int i;
};
Test g_Object;
void func()
{
printf("%d\n",g_Object.getI());
g_Object.setI(55);
}
int main()
{
g_Object.setI(23);
Testte;
te.setI(32);
func();
printf("%d,%d\n",te.getI(), g_Object.getI());
return 0;
}
类Test私有成员变量i具有类作用域,它只能在成员函数setI和getI中使用。程序中定义了两个对象:全局对象g_Object和局部对象te。程序中只能使用它们公开的成员函数即g_Object.getI、g_Object.setI和te.setI、te.getI,且前两个函数的作用域与对象g_Object的相同,后两个函数的作用域与对象te的相同。
值得注意的是,在类Test定义中成员函数setI和getI直接使用了私有成员变量i,但通过对象调用成员函数setI和getI时,它们操作了相关对象的成员变量,即通过对象g_Object使用成员函数时,成员函数操作了g_Object的私有成员变量i,而通过对象te使用成员函数时,成员函数操作了te的私有成员变量i。
这个程序的运行结果与上面的相同。
问题:
1)假设成员函数setI被定义为void setI(int value){int i; i =value;}会出现什么情况?会出错吗?为什么?
2)假设成员函数setI被定义为void setI(int i){i = i;}会出现什么情况?
思考:
成员函数为何可以正确区分相关的对象?
编译系统会“改写”成员函数,自动为成员函数添加一个形参,如成员函数setI可能被改写为voidsetI(int value, Test *this){this->i = value;}。
同时,它还会改写函数调用,如g_Object.setI(23)会被改写为g_Object.setI(23, g_Object);而te.setI(32)会被改写为te.setI(32,&te)。
这样一来,通过对象调用成员函数时,成员函数自然可以区分出每个对象。
注意:可以在成员函数中直接使用this指针变量。转载地址:http://hcdti.baihongyu.com/