c++ primer 学习笔记23 友元 static类成员

来源:互联网 发布:网络交友的好处和弊端: 编辑:程序博客网 时间:2024/06/09 21:46

友元机制允许一个类将对其非公有成员的访问权授予指定的函数或类。友元的声明以关键字 friend 开始。它只能出现在类定义的内部。友元声明可以出现在类中的任何地方:友元不是授予友元关系的那个类的成员,所以它们不受声明出现部分的访问控制影响。
通常,将友元声明成组地放在类定义的开始或结尾是个好主意。
友元可以是普通的非成员函数,或前面定义的其他类的成员函数,或整个类。将一个类设为友元,友元类的所有成员函数都可以访问授予友元关系的那个类的非公有成员。
使其他类的成员函数成为友元
如果不是将整个 Window_Mgr 类设为友元,Screen 就可以指定只允许relocate 成员访问:

 class Screen {          // Window_Mgrmust be defined before class Screen          friend Window_Mgr&              Window_Mgr::relocate(Window_Mgr::index,                                   Window_Mgr::index,                                   Screen&);          // ...restofthe Screen class      }; 

当我们将成员函数声明为友元时,函数名必须用该函数所属的类名字加以限定。
更一般地讲,必须先定义包含成员函数的类,才能将成员函数设为友元。另一方面,不必预先声明类和非成员函数来将它们设为友元。

static 类成员

通常,非 static 数据成员存在于类类型的每个对象中。不像普通的数据成员,static 数据成员独立于该类的任意对象而存在;每个 static 数据成员是与类关联的对象,并不与该类的对象相关联。
正如类可以定义共享的 static 数据成员一样,类也可以定义 static 成员函数。static 成员函数没有 this 形参,它可以直接访问所属类的 static 成员,但不能直接使用非 static 成员。
使用类的 static 成员的优点
使用 static 成员而不是全局对象有三个优点。
1. static 成员的名字是在类的作用域中,因此可以避免与其他类的成员或全局对象名字冲突。
2. 可以实施封装。static 成员可以是私有成员,而全局对象不可以。
3. static 成员是与特定类关联的。这种可见性可清晰地显示程序员的意图。

 class Account {      public:          // interface functions here          void applyint() { amount += amount * interestRate; }          static double rate() { return interestRate; }          static void rate(double); // sets a new rate      private:          std::string owner;          double amount;          static double interestRate;          static double initRate();      }; 

使用类的 static 成员
可以通过作用域操作符从类直接调用 static 成员,或者通过对象、引用或指向该类类型对象的指针间接调用。

     Account ac1;      Account *ac2 = &ac1;      // equivalent ways to call the static member rate function      double rate;      rate = ac1.rate();        // through an Account object or reference      rate = ac2->rate();       // through a pointer to an Account object      rate = Account::rate();   // directly from the class using the scope operator 

static 成员函数
Account 类有两个名为 rate 的 static 成员函数,其中一个定义在类的内部。当我们在类的外部定义 static 成员时,无须重复指定 static 保留字,该保留字只出现在类定义体内部的声明处:

 void Account::rate(double newRate)      {          interestRate = newRate;      } 

static 函数没有 this 指针
static 成员是类的组成部分但不是任何对象的组成部分,因此,static 成员函数没有 this 指针。
因为 static 成员不是任何对象的组成部分,所以 static 成员函数不能被声明为 const。毕竟,将成员函数声明为 const 就是承诺不会修改该函数所属的对象。最后,static 成员函数也不能被声明为虚函数。
static 数据成员
static 数据成员必须在类定义体的外部定义(正好一次)。不像普通数据成员,static 成员不是通过类构造函数进行初始化,而是应该在定义时进行初始化。
可以定义如下 interestRate:

  // define and initialize static class member      double Account::interestRate = initRate(); 

像使用任意的类成员一样,在类定义体外部引用类的 static 成员时,必须指定成员是在哪个类中定义的。然而,static 关键字只能用于类定义体内部的声明中,定义不能标示为 static。
特殊的整型 const static 成员
一般而言,类的 static 成员,像普通数据成员一样,不能在类的定义体中初始化。相反,static 数据成员通常在定义时才初始化。
这个规则的一个例外是,只要初始化式是一个常量表达式,整型 const static 数据成员就可以在类的定义体中进行初始化:

 class Account {      public:          static double rate() { return interestRate; }          static void rate(double);  // sets a new rate      private:          static const int period = 30; // interest posted every 30 days          double daily_tbl[period]; // ok: period is constant expression      }; 

const static 数据成员在类的定义体中初始化时,该数据成员仍必须在类的定义体之外进行定义。

在类内部提供初始化式时,成员的定义不必再指定初始值:      // definition of static member with no initializer;      // the initial value is specified inside the class definition      const int Account::period; 
0 0