http://www.cplusplus.com/doc/tutorial/classes/
类可以包含数据成员,也可以包含函数成员。类的格式如下:
class class_name { access_specifier_1: member1; access_specifier_2: member2; ... } object_names;
#include <iostream> using namespace std; class Rectangle { int width, height; public: void set_values(int ,int); int area(void){ return (width*height); } }; void Rectangle::set_values(int x, int y){ width = x; height = y; } int main() { Rectangle rect; rect.set_values(3,4); cout << "area: "<<rect.area()<<endl; return 0; }
在这里,我们声明(Declare)了一个类(class)叫做Rectagnle。注意,类的后面省去了对象名(object_name)。
Rectangle类中定义了四个成员,两个int类型数据成员(data member)——width,height。两个成员函数——set_values,area。
数据成员(或者属性)的访问权限没有写,但是我们需要知道该访问权限是私有的private。因为类的默认访问权限为私有。【与结构体struct不同,结构体默认为公有访问权限,对了,如果你把class关键字改为struct编译运行,程序仍然可以运行通过】。因此,这两个数据成员只能在类中,或者友元(friend)中访问。
正如大多数的程序猿做的一样,在public访问权限的函数中访问这些私有属性。为啥不在友元中访问?在面向对象中,类是一个完整的自我包含的整体。就像是人这个类,吃饭睡觉是自己告诉自己,我饿了我该吃饭了,我累了我该歇歇了。而不是别人告诉你,说你饿了,你该吃饭了,然后别人握着你的下巴帮你咀嚼食物。。。。。
在main()函数中,多说一句话,main函数式函数的入口,在很多次的上机实习中,令我惊讶的是,有一部分学生在编写完类之后,不写main函数,然后说,老师,我的程序写好了,就是没有输出。。。。;哎。。。。;他说的输出是指没有弹出那个黑框框。。。。。。。
main函数中,
Rectangle rect;Rectangle是类名(class name), rect是对象名(object name);
就像是:
int i_a;
当我们对i_a赋值时,一般使用 cin >> i_a; 将键盘输入值定向到变量i_a中。然而,在类Rectangle后面的main函数中,我们使用:
rect.set_values(3,4);Rectangle类对象rect告诉自己说,我要设置值。然后就调用了自己的函数set_values并传入值3和4。因为set_values是public访问权限,因此在类的外部——main函数中可以通过对象名.函数名的方式,进行访问。
至于两个数据成员,因为它们是私有的。因此,不能使用rect.变量名的方式,为其赋值或取值。这也进一步保证了类的安全——防止通过类对象.数据成员方式修改数据,将其赋值一个非int类型,或者其他种种。
访问类中public访问权限的变量或者函数,只需要在对象名(object name)和成员名(member name)之间加一个点号·(dot)。 (成员(member)包括数据成员(data member) 和 成员函数(member function)) 。
如: rect.set_values(3,4) 和 rect.area();
紧接着,再看看两个公开访问权限(public)的函数set_values和area。
在类中有这样一句话:
void set_values(int ,int);它与
void set_values(int , int ){;} // 这里在声明set_values函数的同时,对其进行了定义。 // 定义部分在花括号中{;}它是一个空的函数体。 // 但是它的确是定义,虽然里面只有一个分号。
返回值类型 类名+域解析运算符::(scope operator)+函数名(参数列表)
的形式对该函数进行定义:
void Rectangle::set_values(int x, int y){ width = x; height = y; }这里,如函数声明一样,返回值类型是void类型,也就是函数中没有return语句。紧接着,要告诉编译器set_values函数是Rectangle类中的——Rectangle::set_values
后面的参数列表保持一致。
除此之外,我们看到了如何通过传参的形式,对类中的两个私有访问权限的width和height的值进行修改。在set_values函数中,通过赋值语句,width= x和height=y;将传入的两个整型的值x,y分别赋给width和height。而x和y的值,就是main函数中rect.set_values(3,4) 的3和4。
在看一下Rectangle类中的area函数。与set_values不同的是,它的定义就在类中。因为它是一句很短很短的话。
return (width*height);因为这里有个return语句。所以,返回值类型写的是int类型。或者说,因为我们想通过area函数获得一个值,而且这个值是整型的,所以在返回值类型上写的是int。而在函数体中使用的是return语句。return的是宽×高的乘积。这样,我们就可以在main函数中将其返回值输出 cout<<"area: "<< rect.area();。
int area(void){ return (width*height); } // 返回值类型: int; 函数名: area ; 函数参数列表:空(void),如果参数列表为空, // 可以将void省去。如: int area(){return width*height;}因为这句话非常短,因此可以将其视为内联(inline),而直接将其写入到类声明中。
当然,你也可以将set_values的定义也写在类中,但是如果这个类中有很多很多的函数,而且这些函数的实现(定义)也都写在类中的话,势必会导致看起来很混乱,而且整个类文件非常的长。。。。。
内联(inline)和非内联(not-inline)的区别是什么?这里引用www.cpluscplus.com中的一句话:“This causes no differences in behavior, but only on possible complier optimizations.” 在行为上没有什么区别(都完成了相应的动作),但是在编译器优化上,可能会有小小的区别。
当然,我们还可以使用Rectangle类同时定义两个类对象:
Rectangle recta, rectb; recta.set_values(3,4); rectb.set_values(4,5); cout<<"recta area: "<<recta.area(); cout<<"rectb area: "<<rectb.area();完整代码:
#include <iostream> using namespace std; class Rectangle { int width, height; public: void set_values(int ,int); int area(void){ return (width*height); } }; void Rectangle::set_values(int x, int y){ width = x; height = y; } int main() { Rectangle recta, rectb; recta.set_values(3,4); rectb.set_values(4,5); cout<<"recta area: "<<recta.area()<<endl; cout<<"rectb area: "<<rectb.area()<<endl; return 0; }
程序输出:
recta area: 12 rectb area: 20