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--; };
};
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;
}
|
7
6 |
实际上,静态成员与全域变量(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的直接成员。
类之间的关系(Relationships between classes)
友元函数(Friend functions)
在前面的章节中我们已经看到了对class的不同成员存在3个层次的内部保护:public, protected 和 private。在成员为 protected 和 private的情况下,它们不能够被从所在的class以外的部分引用。然而,这个规则可以通过在一个class中使用关键字friend来绕过,这样我们可以允许一个外部函数获得访问class的protected 和 private 成员的能力。
为了实现允许一个外部函数访问class的private 和 protected 成员,我们必须在class内部用关键字friend来声明该外部函数的原型,以指定允许该函数共享class的成员。在下面的例子中我们声明了一个 friend 函数 duplicate:
// friend functions
#include <iostream.h>
class CRectangle {
int width, height;
public:
void set_values (int, int);
int area (void) {return (width * height);}
friend CRectangle duplicate (CRectangle);
};
void CRectangle::set_values (int a, int b) {
width = a;
height = b;
}
CRectangle duplicate (CRectangle rectparam) {
CRectangle rectres;
rectres.width = rectparam.width*2;
rectres.height = rectparam.height*2;
return (rectres);
}
int main () {
CRectangle rect, rectb;
rect.set_values (2,3);
rectb = duplicate (rect);
cout << rectb.area();
}
|
24 |
函数duplicate是CRectangle的friend,因此在该函数之内,我们可以访问CRectangle 类型的各个object的成员 width 和 height。注意,在 duplicate()的声明中,及其在后面main()里被调用的时候,我们并没有把duplicate 当作class CRectangle的成员,它不是。
|