C++初步(5)

来源:互联网 发布:用织梦cms侵权 编辑:程序博客网 时间:2024/06/12 01:01
  1. 类(class)
    是一种将数据和函数组织在同一个结构里的逻辑方法。定义类的关键字为class ,其功能与C语言中的struct类似,不同之处是class 可以包含函数 ,而不像struct只能包含数据元素。
    类定义的形式是:

    class class_name {    permission_label_1:        member1;    permission_label_2:        member2;    ...} object_name;//一个或几个对象(object)标识
  2. Class的声明体中包含成员members,成员可以是数据或函数定义,同时也可以包括允许范围标志 permission labels,范围标志可以是以下三个关键字中任意一个:private:,public:,protected
    它们分别代表以下含义:

    private :class的private成员,只有**同一个class的其他成员或该class的“friend” class(友类)**可以访问这些成员。protected :class的protected成员,只有**同一个class的其他成员,或该class的“friend” class,或该class的子类(derived classes) ** 可以访问这些成员。 public :class的public成员, **任何可以看到这个class的地方** 都可以访问这些成员。

    在定义一个class成员的时候没有声明其允许范围,这些成员将被默认为 private范围

    class CRectangle {            int x, y;        public:            void set_values (int,int);            int area (void);    } rect;

    上面例子定义了一个class CRectangle 和该class类型的对象变量rect 。这个class 有4个成员:
    两个整型变量 (x 和 y) ,在private 部分 (因为private 是默认的允许范围);
    以及两个函数, 在 public 部分,这里只包含了函数的原型(prototype)。

    rect.set_value (3,4);myarea = rect.area();//实现引用

    但是,不能够引用 x 或 y ,因为它们是该class的 private 成员,它们只能够在该class的其它成员中被引用

     // classes example    #include <iostream.h>    class CRectangle {            int x, y;        public:            void set_values (int,int);            int area (void) {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();    }                   //12

    范围操作符(双冒号:: )用来在一个class之外定义该class的成员。在CRectangle class内部已经定义了函数area() 的具体操作,因为这个函数非常简单。而对函数set_values() ,在class内部只是定义了它的原型prototype,而其实现是在class之外定义的。这种在class之外定义其成员的情况必须使用范围操作符::
    范围操作符 (::) 声明了被定义的成员所属的class名称,并赋予被定义成员适当的范围属性,这些范围属性与在class内部定义成员的属性是一样的
    例如,在上面的例子中,在函数set_values() 中引用了private变量x 和 y,这些变量只有在class内部和它的成员中才是可见的。
    在class内部直接定义完整的函数,和只定义函数的原型而把具体实现放在class外部的唯一区别在于,在第一种情况中,编译器(compiler) 会自动将函数作为inline 考虑,而在第二种情况下,函数只是一般的class成员函数。
    把 x 和 y 定义为private 成员 (记住,如果没有特殊声明,所有class的成员均默认为private ),原因是已经定义了一个设置这些变量值的函数 (set_values()) ,这样一来,在程序的其它地方就没有办法直接访问它们。这样保护两个变量有重要意义,在比较复杂的程序中,使得变量不会被意外(这里意外指的是从object的角度来讲的意外)修改。
    使用class的一个更大的好处是可以用它来定义多个不同对象(object),之间没有干扰。
    这是基于对象( object) 和面向对象编程 (object-oriented programming)的概念的。这个概念中,数据和函数是对象(object)的属性(properties),而不是像以前在结构化编程 (structured programming) 中所认为的对象(object)是函数参数。
    这里有实例(instance),或称对象(object)

  3. 构造函数和析构函数 (Constructors and destructors)
    对象(object)在生成过程中通常需要初始化变量或分配动态内存,以便能够操作,或防止在执行过程中返回意外结果。例如,在前面的例子中,如果我们在调用函数set_values( ) 之前就调用了函数area(),将会产生什么样的结果呢?可能会是一个不确定的值,因为成员x 和 y 还没有被赋于任何值。
    为了避免这种情况发生,一个class 可以包含一个特殊的函数:构造函数constructor,它可以通过声明一个与class同名的函数来定义。当且仅当要生成一个class的新的实例 (instance)的时候,也就是当且仅当声明一个新的对象,或给该class的一个对象分配内存的时候,这个构造函数将自动被调用。

     // class example    #include <iostream.h>    class CRectangle {        int width, height;      public:        CRectangle (int,int);        /*构造函数*/        int area (void) {return (width*height);}    };    CRectangle::CRectangle (int a, int b) {        width = a;        height = b;    }/*原型和实现中都没有返回值(return value),也没有void 类型声明。构造函数必须这样写。一个构造函数永远没有返回值,也不用声明void*/    int main () {        CRectangle rect (3,4);        CRectangle rectb (5,6);        //参数在class实例 (instance)生成的时候传递给构造函数        cout << "rect area: " << rect.area() << endl;        cout << "rectb area: " << rectb.area() << endl;    }    

    析构函数Destructor 完成相反的功能。它在objects被从内存中释放的时候被自动调用。释放可能是
    因为它存在的范围已经结束了(例如,如果object*被定义为一个函数内的本地(local)对象变量,而该函数结束了*);
    或者是因为它是一个动态分配的对象,而被使用操作符delete 释放了。
    析构函数必须与class同名,加水波号tilde (~) 前缀,必须无返回值。
    析构函数特别适用于当一个对象被动态分配内存空间,而在对象被销毁的时我们希望释放它所占用的空间的时候。

    // example on constructors and destructors#include <iostream.h>class CRectangle {    int *width, *height;  public:    CRectangle (int,int);    ~CRectangle ();//析构函数    int area (void) {return (*width * *height);}};CRectangle::CRectangle (int a, int b) {    width = new int;    height = new int;    *width = a;    *height = b;}CRectangle::~CRectangle () {    delete width;    delete height;}//自己定义。。。int main () {    CRectangle rect (3,4), rectb (5,6);    cout << "rect area: " << rect.area() << endl;    cout << "rectb area: " << rectb.area() << endl;    return 0;}

    构造函数重载(Overloading Constructors)像其它函数一样,一个构造函数也可以被多次重载(overload)为同样名字的函数,但有不同的参数类型和个数。编译器在这里则是调用与类对象被声明时一样的那个构造函数。
    实际上,当我们定义一个class而没有明确定义构造函数的时候,编译器会自动假设两个重载的构造函数 (默认构造函数”default constructor” 和复制构造函数”copy constructor”)。例如,对以下class:

       class CExample {     public:       int a,b,c;       void multiply (int n, int m) { a=n; b=m; c=a*b; }   };

    没有定义构造函数,编译器自动假设它有以下constructor 成员函数:
    Empty constructor
    它是一个没有任何参数的构造函数,被定义为nop (没有语句)。它什么都不做。

    CExample::CExample () { };

    Copy constructor
    它是一个只有一个参数的构造函数,该参数是这个class的一个对象,这个函数的功能是将被传入的对象(object)的所有非静态(non-static)成员变量的值都复制给自身这个object

       CExample::CExample (const CExample& rv) {       a=rv.a;  b=rv.b;  c=rv.c;   }

    这两个默认构造函数(empty construction 和 copy constructor )只有在没有其它构造函数被明确定义的情况下才存在。如果任何其它有任意参数的构造函数被定义了,这两个构造函数就都不存在了。在这种情况下,如果你想要有empty construction 和 copy constructor ,就必需要自己定义它们。

       // overloading class constructors    #include <iostream.h>    Class CRectangle {        int width, height;      public:        CRectangle ();        CRectangle (int,int);        int area (void) {return (width*height);}    };    CRectangle::CRectangle () {        width = 5;        height = 5;    }    CRectangle::CRectangle (int a, int b) {        width = a;        height = b;    }    int main () {        CRectangle rect (3,4);        CRectangle rectb;        //传入参数的方式以及参数的有无,都得看构造函数的形式。        cout << "rect area: " << rect.area() << endl;        cout << "rectb area: " << rectb.area() << endl;    }

    在上面的例子中,rectb 被声明的时候没有参数,所以它被使用没有参数的构造函数进行初始化,也就是width 和height 都被赋值为5。
    在我们声明一个新的object的时候,如果不想传入参数,则不需要写括号():

    CRectangle rectb; // rightCRectangle rectb(); // wrong! 
  4. 类的指针(Pointers to classes)

    CRectangle * prect;//是一个指向class CRectangle类型的对象的指针。就像数据机构中的情况一样,要想直接引用一个由指针指向的对象(object)中的成员,需要使用操作符 ->。

    以下是怎样读前面例子中出现的一些指针和类操作符 (*, &, ., ->, [ ]):

    *x 读作: pointed by x (由x指向的)&x 读作: address of x(x的地址)x.y 读作: member y of object x (对象x的成员y)(*x).y 读作: member y of object pointed by x(由x指向的对象的成员y)x->y 读作: member y of object pointed by x (同上一个等价)x[0] 读作: first object pointed by x(由x指向的第一个对象)x[1] 读作: second object pointed by x(由x指向的第二个对象)x[n] 读作: (n+1)th object pointed by x(由x指向的第n+1个对象)
  5. 由关键字struct和union定义的类
    类不仅可以用关键字class来定义,也可以用struct或union来定义。
    因为在C++中类和数据结构的概念太相似了,所以这两个关键字struct和class的作用几乎是一样的(也就是说在C++中struct定义的类也可以有成员函数,而不仅仅有数据成员)。两者定义的类的唯一区别在于由class定义的类所有成员的默认访问权限为private,而struct定义的类所有成员默认访问权限为public
    union的概念与struct和class定义的类不同, 因为union在同一时间只能存储一个数据成员但是由union定义的类也是可以有成员函数的。union定义的类访问权限默认为public

0 0
原创粉丝点击