C++初步(6)

(忽然意识到,不能无谓的copy,于己并无益处,还自以为学到了东西。应该摘录那些有意义的内容。)

操作符重载(Overloading operators)

    struct { 
        char product [50]; 
        float price; 
    } a, b, c;
    a = b + c; 

将一个类class (或结构struct)的对象赋给另一个同种类型的对象是允许的(通过使用默认的复制构造函数 copy constructor)。但相加操作就有可能产生错误,理论上讲它在非基本数据类型之间是无效的。

但归功于C++ 的操作符重载(overload)能力,我们可以完成这个操作。像以上例子中这样的组合类型的对象在C++中可以接受如果没有操作符重载则不能被接受的操作,我们甚至可以修改这些操作符的效果。要想重载一个操作符,我们只需要编写一个成员函数,名为operator ,后面跟我们要重载的操作符,遵循以下原型定义:

    type operator sign (parameters);

如下例:

    // vectors: overloading operators example
    #include <iostream.h>

    class CVector {
      public:
        int x,y;
        CVector () {};
        CVector (int,int);
        CVector operator+ (CVector);
    };

    CVector::CVector (int a, int b) {
        x = a;
        y = b;
    }

    CVector CVector::operator+ (CVector param) {
        CVector temp;
        temp.x = x + param.x;
        temp.y = y + param.y;
        return (temp);
    }

    int main () {
        CVector a (3,1);
        CVector b (1,2);
        CVector c;
        c = a + b;
        cout << c.x << "," << c.y;
        return 0;
    }    

其中

    CVector (int, int);            // 函数名称 CVector (constructor)
    CVector operator+ (CVector);   // 函数 operator+ 返回CVector 类型的值

Class CVector的函数 operator+ 是对数学操作符+进行重载的函数这个函数可以用以下两种方法进行调用:

    c = a + b;
    c = a.operator+ (b); 

在这个例子中包括了一个空构造函数 (无参数),而且我们将它定义为无任何操作:

    CVector ( ) { };

这是很必要的,因为例子中已经有另一个构造函数,

    CVector (int, int);

如果不像上面这样明确定义一个的话,CVector的两个默认构造函数都不存在。这样的话,main( )中包含的语句

    CVector c;

将为不合法的。尽管如此,一个空语句块 (no-op block)并不是一种值得推荐的构造函数的实现方式,因为它不能实现一个构造函数至少应该完成的基本功能,也就是初始化class中的所有变量。例子中,这个构造函数没有完成对变量x 和 y 的定义。

因此一个更值得推荐的构造函数定义应该像下面这样:

    CVector ( ) { x=0; y=0; }; 

一个class默认包含一个空构造函数和一个复制构造函数,包含一个对赋值操作符assignation operator (=)的默认定义。后者用于两个同类对象之间。这个操作符将其参数对象(符号右边的对象) 的所有非静态 (non-static) 数据成员复制给其左边的对象。(当然,也可以再定义)

重载一个操作符并不要求保持其常规的数学含义,虽然这是推荐的。(有两种方法重载一些class操作符:作为成员函数(member function)或作为全域函数(global function)。)

关键字 this

关键字this通常被用在一个class内部,指正在被执行的该class的对象(object)在内存中的地址。它是一个指针,其值永远是自身object的地址。

可以被用来检查传入一个对象成员函数的参数是否是该对象本身。

    // this
    #include <iostream.h>

    class CDummy {
        public:
            int isitme (CDummy& param);
        };

    int CDummy::isitme (CDummy& param) {
        if (&param == this) return 1;
        else return 0;
    }

    int main () {
        CDummy a;
        CDummy* b = &a;
        if ( b->isitme(a) )
            cout << "yes, &a is b";
        return 0;
    }

它还经常被用在成员函数operator= 中,用来返回对象的指针(避免使用临时对象)。以下用前面看到的向量(vector)的例子来看一下函数operator= 是怎样实现的:

       CVector& CVector::operator= (const CVector& param) {
            x=param.x;
            y=param.y;
            return *this;
       }

实际上,如果我们没有定义成员函数operator=,编译器自动为该class生成的默认代码有可能就是这个样子的。

静态成员(Static members)

一个class 可以包含静态成员(static members),可以是数据,也可以是函数。
一个class的静态数据成员也被称作类变量”class variables”,因为它们的内容不依赖于某个对象,对同一个class的所有object具有相同的值。

例如,它可以被用作计算一个class声明的objects的个数,见以下代码程序:

    // static members in classes
    #include <iostream.h>

    class CDummy {
      public:
        static int n;
        CDummy () { n++; };
        ~CDummy () { n--; };
    };//可以注意的是,class后面有分号。

    int CDummy::n=0;

    int main () {
        CDummy a;
        CDummy b[5];
        CDummy * c = new CDummy;
        cout << a.n << endl;
        delete c;
        cout << CDummy::n << endl;  
        return 0;
    } 

静态成员与全域变量(global variable)具有相同的属性,但它享有类(class)的范围

根据ANSI-C++ 标准,为了避免它们被多次重复声明,在class的声明中只能够包括static member的原型(声明),而不能够包括其定义(初始化操作)。为了初始化一个静态数据成员,我们必须在class之外(在全域范围内),包括一个正式的定义,就像上面例子中做法一样。

因为它对同一个class的所有object是同一个值,所以它可以被作为该class的任何object的成员所引用,或者直接被作为class的成员引用(当然这只适用于static 成员):

    cout << a.n;
    cout << CDummy::n;

以上两个调用都指同一个变量:class CDummy里的static 变量 n 。它其实是一个全域变量。唯一的不同是它的名字跟在class的后面。

就像会在class中包含static数据一样,也可以使它包含static 函数。它们表示相同的含义:static函数是全域函数(global functions),但是像一个指定class的对象成员一样被调用。它们只能够引用static 数据,永远不能引用class的非静态(nonstatic)成员。它们也不能够使用关键字this,因为this实际引用了一个对象指针,但这些 static函数却不是任何object的成员,而是class的直接成员。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值