C++开发中级


848 浏览 5 years, 4 months

4.4 独立的子类

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

独立的子类

编写StringSpreadsheetCell以及DoubleSpreadsheetCell类只需要实现在父类中定义的功能。因为想让客户能够实现并使用字符串单元格以及双精度值单元格,因此单元格不应该是抽象的—必须实现从父类继承的所有纯虚方法。

1. 电子表格字符串单元格的类定义

编写StringSpreadsheetCell类定义的第一步是从SpreadsheetCell类继承:

class StringSpreadsheetCell : public SpreadsheetCell
{

可将StringSpreadsheetCell数据值初始化为“#NOVALUE",以说明这个值尚未设置。编译器生成的默认构造函数将调用string默认的构造函数,将mValue初始化为空字符串””。因此应该提供一个显式的默认构造函数并初始化值。

随后重写继承的纯虚方法,这时候不能使用=0:

  virtual void set(const std::string& inString);
  virtual std::string getString() const;

最后,字符串单元格添加了一个protected数据成员mValue来存储实际的单元格数据:

std::string mValue;
2. 电子表格字符串单元格的实现

StringSpreadsheetCell类的.cpp文件比基类有趣一些。在构造函数中,mValue被初始化为一个表明还没有设置值的字符串。

StringSpreadsheetCell::StringSpreadsheetCell():mValue("#NOVALUE"){  
}

Set()方法相当直接,因为数据的内部表示已经是字符串。与此类似,getString()方法返回存储的值。

void StringSpreadsheetCell::set(const std::string& inString){
    mValue = inString
}

string StringSpreadsheetCell::getString() const{
    return mValue;
}
3.电子表格双精度值单元格类的定义以及实现

双精度版本遵循类似的模式,但具有不同的逻辑。除了用字符串做参数的set()方法之外,还提供了新的set()方法允许用户用双精度值做参数。两个新的protected方法用于转换字符串以及双精度值。与StringSpreadsheetCell相同,这个类也有一个名为mValue的数据成员,此时这个成员的类型是double。由于DoubleSpreadsheetCell以及StringSpreadsheetCell是同级类(siblings),因此不存在名称冲突:

class DoubleSpreadsheetCell : public SpreadsheetCell
{
 public:

  DoubleSpreadsheetCell();
  virtual void set(double inDouble);
  virtual void set(const std::string& inString);
  virtual std::string getString() const;
 protected:
  static std::string doubleToString(double inDouble);
  static double stringToDouble(const std::string inValue);
  double mValue;
};

DoubleSpreadsheetCell构造函数的实现如下所示:

DoubleSpreadsheetCell::DoubleSpreadsheetCell():mValue(-1){  
}

为了保持示例的简洁,mValue的值初始化为-1。在产品代码中,或许应该将其初始化为NaN,表示“不是一个数字”。在C++中,可以用std::numeric_limits<double>::quiet_NaN()完成这一任务。 用双精度值做参数的set()方法简单明了。采用字符串做参数的set()方法使用了protected static stringToDouble()方法。getString()方法将存储的双精度值转换为字符串。

void DoubleSpreadsheetCell::set(double inDouble){
    mValue = inDouble
}

void DoubleSpreadsheetCell::set(const std::string& inString){
    mValue = stringToDouble(inString);
}

string DoubleSpreadsheetCell::getString() const{
    return doubleToString(mValue);
}

您或许已经看到了在层次结构中电子表格单元格实现的主要优点—代码更加简单。您不需要使用两个字段来代表两种类型的数据。每个对象都以自我为中心,并且只能执行各自的功能。

注意在此省略了doubleToString()以及stringToDouble()的实现,因为与前面的实现相同。