C++开发初级


1100 浏览 5 years, 4 months

9 友元

版权声明: 转载请注明出处 http://www.codingsoho.com/

友元

C++允许某个类将其他类、其他类的成员函数或者非成员函数声明为友元,友元可以访问类的protected, private数据成员以及方法。例如,SpreadsheetCell可以将Spreadsheet类指定为友元,如下所示:

class SpreadsheetCell
{
 public:
  friend class Spreadsheet;

};

现在,Spreadsheet类所有的方法都可以访问SpreadsheetCell类的private,protected数据成员以及方法。如果只想将Spreadsheet类的某个成员函数作为友元,可使用如下代码:

class SpreadsheetCell
{
 public:
  friend void Spreadsheet::setCellAt(int x, int y, const SpreadsheetCell& cell);
  // .......
};

代码取自 Friends\FriendMethod\SpreadsheetCell.h

注意类需要知道哪些类、方法或者函数希望成为友元;类、方法或者函数不能将自身声明为其他类的友元并访问这些类的非公有名称。

您或许想编写一个函数来验证SpreadsheetCell对象的字符串是否为空。为了模拟外部审查,您或许想将这个验证例程放在SpreadsheetCell类的外部,但是这个函数需要访问对象的内部数据成员以验证其正确性。下面的SpreadsheetCell类定义声明了友元函数checkSpreadsheetCell()。

class SpreadsheetCell
{
 public:
  friend bool checkSpreadsheetCell(const SpreadsheetCell& cell);
};

代码取自 Friends\SpreadsheetCell.h

在类中的friend声明用作函数原型,在其他地方不需要编写这个原型(尽管这么做也没坏处)。下面是函数定义:

bool checkSpreadsheetCell(const SpreadsheetCell& cell)
{
  return !(cell.mString.empty());
}

代码取自 Friends\SpreadsheetCell.cpp

这个函数的定义与其他函数相似,只是您可以用这个函数直接访问SpreadsheetCell类的private以及protected数据成员。在函数定义中不需要再使用friend关键字。

friend类以及方法很容易被滥用;友元可以让您违反抽象的原则,将类的内部暴露给其他类或者函数。因此,只有在特定的情况下(例如运算符重载)才应该使用它们,因为在运算符重载的情况下需要访问protected以及private成员,下一节将讨论与此相关的内容。