Classes(I) 类(一)

http://www.cplusplus.com/doc/tutorial/classes/

类可以包含数据成员,也可以包含函数成员。类的格式如下:

class class_name {
  access_specifier_1:
      member1;
  access_specifier_2:
      member2;
  ...
} object_names;

object_names 可选。与结构体不同,类可以包含函数(functions)和访问限定符(access specifiers)。访问限定符常用的有private,public, protected。

  • private members of a class are accessible only from within other members of the same class (or from their "friends"). 类中/友元
  • protected members are accessible from other members of the same class (or from their "friends"), but also from members of their derived classes.类中/友元/派生类
  • Finally, public members are accessible from anywhere where the object is visible 任何

#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;

使用int类型(类),然后后面是个变量名(类对象)。如果从面向对象的角度来看,int i_a 就是Integer integer_object。从形式(或者语法)上来讲都是一样的。(变量名i_a前面的i告诉我们它是int类型,如果写一个形如d_a,它就是一个double类型)。

当我们对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

你可能感兴趣的:(类,Class)