3、引用数据成员
Spreadsheet与SpreadsheetCell是伟大的,但是不是它们自己就能成为有用的应用程序。需要代码去控制整个spreadsheet程序,可以将其打包成一个SpreadsheetApplication类。假定接下来我们要让每个Spreadsheet来保存一个应用程序对象的引用。这时候SpreadsheetApplication类的确切定义还不太重要,所以下面的代码只是简单地定义了一个空类。Spreadsheet类修改以包含一个新的叫做m_theApp数据成员的引用:
export class SpreadsheetApplication { };export class Spreadsheet
{
public:Spreadsheet(std::size_t width, std::size_t height,SpreadsheetApplication& theApp);// Code omitted for brevity.
private:// Code omitted for brevity.SpreadsheetApplication& m_theApp;
};
该定义添加了一个数据成员SpreadsheetApplication的引用。推荐在这种情况下使用引用而不是指针,因为Spreadsheet应该总是指向SpreadsheetApplication。指针无法保证这一点。
注意对于应用程序的引用的保存只是为了演示引用作为数据成员的使用。不推荐用这种方式将Spreadsheet与SpreadsheetApplication类耦合在一起,应该使用例如MVC的模式。
在构造函数中应用程序的引用给到了每个Spreadsheet。如果不指向任何东西的话引用是无法生存的,所以m_theApp必须在构造函数初始化器中给一个值。
Spreadsheet::Spreadsheet(size_t width, size_t height,const SpreadsheetApplication& theApp): m_id{ ms_counter++ }, m_width{ min(width, MaxWidth) }, m_height{ min(height, MaxHeight) }, m_theApp{ theApp }
{// Code omitted for brevity.
}
在拷贝构造函数中也必须初始化引用成员。这个会自动处理因为Spreadsheet拷贝代理给到了non-copy构造函数,它初始化引用数据成员。
记住在初始化引用之后,就不可以改变它指向的对象了。不能在赋值操作符中赋值给引用。依据你的使用情况,这可能意味着不能为你的带有数据成员的类提供赋值操作符。如果是这样的话,赋值操作符会被标记为删除。
最后,引用数据成员可以被标记为const。例如,你可能会决定 让Spreadsheet卡哇伊有一个对应用程序对象的reference-to-const。可以简单地修改类定义以便将m_theApp声明为reference-to-const:
export class Spreadsheet
{
public:Spreadsheet(std::size_t width, std::size_t height,const SpreadsheetApplication& theApp);// Code omitted for brevity.
private:// Code omitted for brevity.const SpreadsheetApplication& m_theApp;
};