C++开发初级


1005 浏览 5 years, 10 months

5.3 引用数据成员

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

引用数据成员

Spreadsheets以及SpreadsheetCells很好,但是这两个类本身并不能组成非常有用的应用程序。为了用代码控制整个电子表格程序,可将这两个类一起放入SpreadsheetApplication类。

这个类的实现在此并不重要。现在考虑这个架构存在的问题: 电子表格如何与应用程序通信?应用程序存储了电子表格列表,因此可以与电子表格通信。与此类似,每个电子表格都应该存储应用程序对象的引用

Spreadsheet类必须知道SpreadsheetApplication类,SpreadsheetApplication类也必须知道Spreadsheet类。这是一个循环引用问题,无法用普通的#include加以解决。解决方案是在其中一个头文件中使用前置声明(forward declaration)(后面详细介绍)。下面是一个使用了前置声明的新Spreadsheet类定义,用来通知编译器关于SpreadsheetApplication类的信息。

class SpreadsheetApplication; // forward declaration
class Spreadsheet
{
 public:
  Spreadsheet(int inWidth, int inHeight,
          SpreadsheetApplication& theApp);
 protected:
  SpreadsheetApplication& mTheApp;
}; 

代码取自 SpreadsheetDataMembers\Spreadsheet.h

这个定义将一个SpreadsheetApplication引用作为数据成员添加进来。在此情况下建议使用引用而不是指针,因为Spreadsheet总是要引用一个SpreadsheetApplication。而指针则无法保证这一点。

注意存储对应用程序的引用,仅仅是为了演示把引用作为数据成员的用法。不建议以这种方式把SpreadSheet和SpreadSheetApplication类组合在一起,而应该改用MVC(模型-视图-控制器)范例。

注意在构造函数中,每个Spreadsheet都得到了一个应用程序引用。如果不引用某些事物,引用将无法存在,因此在构造函数的ctor-initializer中必须给mTheApp一个值。

Spreadsheet::Spreadsheet(int inWidth, int inHeight,
             const SpreadsheetApplication& theApp)
  : mWidth(inWidth < kMaxWidth ? inWidth : kMaxWidth),
    mHeight(inHeight < kMaxHeight ? inHeight : kMaxHeight), mTheApp(theApp)
{
  // ...
}

代码取自 SpreadsheetDataMembers\Spreadsheet.cpp

在复制构造函数中也必须初始化这个引用成员:

Spreadsheet::Spreadsheet(const Spreadsheet& src) :
  mTheApp(src.mTheApp)
{
  mId = sCounter++;
  copyFrom(src);
}

代码取自 SpreadsheetDataMembers\Spreadsheet.cpp

记住,在初始化一个引用之后,不能改变它引用的对象。因此不需要在赋值运算符中对引用赋值。