全部博文(290)
分类: C/C++
2010-12-10 13:43:19
Classes (I)
类是一个扩展的数据结构概念:它包含的不仅是数据,它是数据和函数的封装体..
对象是类的实例化.依照变量而言,类可作为类型,而对象就是这种类型的变量.
通常,使用关键字class来声明类,并有如下格式:
class class_name {
access_specifier_1:
member1;
access_specifier_2:
member2;
...
} object_names;
Class_name 是一个适合于类的有效标识符,object_name 是一个以这种类型命名的可选对象列表.类体内包含着成员的声明,可以是数据或函数声明,并可随意的指定存取说明符(访问权限)
除了现在我们能包含函数和成员外,还有一个称为存取说明符的新东西,所有的一切都和结构的声明非常相似.存取说明符作为下面三种关键字的其中一种: private,public或protected .这些说明符按如下需要修改成员的访问权限:
一个类的私有成员只能被同属于一个类的其它成员或它们的友元访问.
保护成员不仅能被同属于一个类的成员或者友元访问,而且还可以被这个类的派生类的成员访问.
最后.只要对象可见的任何地方,公有成员都能被访问.
所有使用关键字class声明的类的所有成员的默认访问权限都是私有的.因此,声明在类中任何权限说明符之前的成员都自动的拥有私有访问权限,例如:
class CRectangle {
int x, y;
public:
void set_values (int,int);
int area (void);
} rect;
声明一个称为CRectangle的类和该类的一个对象rect。这个类保护四个成员,两个int类型的私有数据成员(x成员和y成员)以及两个公有成员函数:set_values() 和 area(),目前,我们只是包含了它们的声明,而不是定义。
注意类名和对象名之间的不同;在上一个例子中,CRectangle是一个类名(类似于类型说明副),而rect 是CRectangle类型的一个对象。它们之间的关系就如同下面声明的int 和a;
int a;
这里,int是类型名(class)而 a 是 变量名(对象)。
在声明了CRectangle和rect之后,只需要在对象名后面跟随一个点号(.)然后是成员的名字,我们就能够在程序体内像引用普通函数和变量一样来引用对象 rect的任意公有成员。 这和我们之前处理那些简单的结构类型数据相类似,例如:
rect.set_values (3,4);
myarea = rect.area();
我们唯一不能从类体外的程序体中访问的rect对象的成员是x和y.因为它们的访问权限私有并且只能被同一个类中的其它成员 访问。
这里是CRectangle类的完整例子:
// classes example
#include
using namespace std;
class CRectangle {
int x, y;
public:
void set_values (int,int);
int area () {return (x*y);}
};
void CRectangle::set_values (int a, int b) {
x = a;
y = b;
}
int main () { CRectangle rect; rect.set_values (3,4);
cout << "area: " << rect.area();
return 0;
}
area: 12
代码中最重要的一个新事物是包含在set_values()函数定义处的范围操作(::) ,它被用于在类的外部定义类中的成员。(类域说明符,用于说明某个成员属于某个类 )
你可能已经注意到成员函数area()的定义极其简易,它被直接定义在CRectangle类的内部。而set_value()仅在类中声明一个原型,但是它的定义却在类体外。在类体外定义时,我们必须使用:: 范围操作符来指定我们定义的函数是类CRectangle的成员而不是一个全局函数。
范围操作符(::) 指定被声明的成员所属的类并授予同样的范围属性,就好像这个函数被直接定义在类别定义中一样。例如,在先前的set_values()函数中,我们能够使用属于CRectangle类的私有数据成员变量x和y,私有成员意味着它们仅能被同一个类的其它成员访问。
在一个类中完全定义一个成员函数和仅在类中说明一个函数原型而在稍后再定义这个函数的区别是第一种情况被编译器自动的识别为一个inline (内联)成员函数,而第二种情况作为类的正常成员函数对待,实际上,函数的行为并没有什么差别。
成员x和y拥有私有访问权限(记住,如果没有特别说明,使用关键字class定义的类的所有成员默认权限为私有(Struct 为公 有)) .通过声明为私有,我们将不能从任何类体以外的地方访问它。这是有意义的,因为我们已经定义了一个函数来设置对象的成员值:这个成员函数是set_values().因此,其余的程序并不需要直接的存取它们,大概是因为例子太简单,很难看出保护这两个变量的实用性,但是在大的项目中,值不能以一种意外的方式修改将变的非常重要(意外是从对象的观点来看)。
类的一个较大的优势在于。作为任意一种类型,我们能够声明这种类型的多个对象,例如,下面是先前定义的CRectangle类,我们能够声明除rect外的另一个对象rectb:
// example: one class, two objects
#include
using namespace std;
class CRectangle {
int x, y;
public:
void set_values (int,int);
int area () {return (x*y);}
};
void CRectangle::set_values (int a, int b) {
x = a;
y = b;
}
int main () {
CRectangle rect, rectb;
rect.set_values (3,4);
rectb.set_values (5,6);
cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0;
}
rect area: 12 rectb area: 30
在这个具体的例子中,类(对象的类型)是我们讨论的CRectangle,它有两个实例或对象,rect 和rectb。每一个都有它们自己的成员变量和成员函数。
注意,调用rect.area()和调用rectb.area()并没有返回同样的结果,这是因为每一个CRectangle类的对象都有它自己成员变量x和y。从某种程度上,它们(对象)同样有它们自己的成员函数set_values()和area(),这些函数对调用它们的对象的成员变量进行操作。
这就是面向对象编程的基本概念:数据和函数都是对象的成员。我们不再使用一个全局变量集,来将其自身作为参数从一个函数传递到另一个函数。我们处理的对象有它们自己的数据和函数作为嵌入的成员。注意,这并不是说我们在调用rect.area 或rectb.area时不需要提供任何参数。这些成员函数使用了各自对象rect和rectb的数据成员。