当前位置: 首页 > news >正文

C++学习笔记----9、发现继承的技巧(四)---- 多态继承(3)

6、未来考虑

        从面向对象设计的角度,新的SpreadsheetCell层次结构的实现确定是一次提升。然而,对于真实世界的spreadsheet程序来说这样的类层次结构还不够,有如下几个原因。

        首先,除了提升的设计,还缺失一个属性:从一个单元格类型转换为另一个的能力。通过分成两个类,单元格对象变得松散了。为了提供将DoubleSpreadsheetCell转化为StringSpreadsheetCell的能力,还要加一个转换构造函数,也叫做类型构造函数。与拷贝构造函数外观类似,但是它不是同一个类的对象的引用,而是一个同胞类的对象的引用。记住现在要声明一个缺省的构造函数,它可以被显式缺省,因为只要你自己一声明任何构造函数,编译器就不会再生成了。

export class StringSpreadsheetCell : public SpreadsheetCell
{
public:StringSpreadsheetCell() = default;StringSpreadsheetCell(const DoubleSpreadsheetCell& cell): m_value{ cell.getString() }{}// Remainder omitted for brevity.	
};

        使用转换构造函数,给定一个DoubleSpreadsheetCell,可以容易地生成一个StringSpreadsheetCell。然而,不要给这些转换指针或引用搞晕。将一个同胞指针或引用从一个转换为另一个是不灵的,除非你重载了转换操作符。

        警告:层次结构上,总是可以向上转换,有时可以向下转换。通过改变cast操作符或使用reinterpret_cast()在层次结构之间转换是可能的,但都不推荐。

        其次,怎么实现单元格的重载的操作符是一个有趣的总是,有几种可能的方法。

        一种方法是实现单元格的每一种组合的操作符的一个版本。对于只有两个继承类,是可管理的。会有一个operator+函数来加两个double单元格,来加两个string单元格 ,以及来加一个double到一个string单元格 。对于每一种组合,要决定结果是什么。例如,两个double单元格相加的结果可以是两个值的算术相加。两个string单元格的相加结果可以是两个string联结的string,等等。

        另一个方法是决定通用表示。早期的实现已经在string上作为各种通用的表示标准化。单独的operator+可以通过利用通用表示囊括所有情况。

        另外一种方法是一个混合。operator+可以提供来添加两个DoubleSpreadsheetCell结果放在DoubleSpreadsheetCell。该操作符可以在double_spreadsheet_cell模块中实现,如下:

export DoubleSpreadsheetCell operator+(const DoubleSpreadsheetCell& lhs,const DoubleSpreadsheetCell& rhs)
{DoubleSpreadsheetCell newCell;newCell.set(lhs.getValue() + rhs.getValue());return newCell;
}

        该操作符可以测试如下:

		DoubleSpreadsheetCell doubleCell;doubleCell.set(8.4);DoubleSpreadsheetCell result{ doubleCell + doubleCell };println("{}", result.getString());  // Prints 16.800000

        当两个操作数中至少一个是StringSpreadsheetCell时提供第二个operator+。可以决定该操作符的结果应该总是一个string单元格。可以给string_spreadsheet_cell模块添加一个这样的操作符,可以实现如下:

export StringSpreadsheetCell operator+(const StringSpreadsheetCell& lhs,const StringSpreadsheetCell& rhs)
{StringSpreadsheetCell newCell;newCell.set(lhs.getString() + rhs.getString());return newCell;
}

        只要编译器有方法将特殊的单元格转换为StringSpreadsheetCell,操作符就管用。拿前面例子中使用DoubleSpreadsheetCell作参数的StringSpreadsheetCell构造函数,如果这是让operator+唯一工作的方式的话,编译器会自动执行转换。这意味着下面的代码将一个double单元格到一个string单元格是可以的,即使只提供了两个operator+的实现:一个是两个double单元格相加,一个是两个string单元格相加。

		DoubleSpreadsheetCell doubleCell;doubleCell.set(8.4);StringSpreadsheetCell stringCell;stringCell.set("Hello ");StringSpreadsheetCell result{ stringCell + doubleCell };println("{}", result.getString());  // Prints Hello 8.400000

        如果对多态还有一点儿不确信,以此例代码开始搞明白它。实验代码练习多态的多个方面是一个伟大的起点。

7、为干净的virtual成员函数提供实现

        从技术上来讲,为干净的virtual成员函数提供实现是可能的。该实现不能在类定义本身,必须在外部提供。虽然类保持抽象,任何继承类仍然要求提供干净的virtual成员函数的实现。由于类保持抽象,不能生成实例。干净的virtual成员函数的实现仍然可以被调用,例如,从继承类,下面的代码段展示了这一点:

class Base
{
public:virtual void doSomething() = 0; // Pure virtual member function.
};// An out-­of-­class implementation of a pure virtual member function.
void Base::doSomething() { println("Base::doSomething()"); }class Derived : public Base
{
public:void doSomething() override{// Call pure virtual member function implementation from base class.Base::doSomething();println("Derived::doSomething()");}
};int main()
{Derived derived;Base& base { derived };base.doSomething();
}

        输出如预期:

Base::doSomething()
Derived::doSomething()


http://www.mrgr.cn/news/56626.html

相关文章:

  • Bitcoin全节点搭建
  • 人工智能--数学基础
  • Coppelia Sim (v-REP)仿真 机器人3D相机手眼标定与实时视觉追踪 (一)
  • Vue使用OnlyOffice预览文档方案
  • MySQL实现主从同步
  • 五、Shell 脚本编程:从基础至实用实例
  • 信号处理入门与实战指南
  • 数据结构修炼——树?二叉树?堆?从入门到代码实现,第二弹!!!
  • 【Spring MVC】请求参数的获取
  • C++ | Leetcode C++题解之第501题二叉搜索树中的众数
  • Construmart借力SNP全面升级SAP S/4HANA和 SAP CAR 改进零售业务流程
  • 【Linux 从基础到进阶】性能测试工具使用(sysbench、fio等)
  • 出现 master -> master (non-fast-forward) error: failed to push some ref 解决方法
  • 【前端】如何制作一个自己的网页(17)无序列表
  • MYSQL-查看创建的事件event语法(十)
  • 推荐一个开源非线性视频编辑器:Kdenlive
  • TwinCAT3下位机配置EAP通讯传递与接收变量
  • jEasyUI 创建自定义视图
  • AI学习指南深度学习篇-对比学习的原理
  • Eclipse Java 构建路径
  • Python学习的自我理解和想法(20)
  • AI 解读软考高级操作系统顺序存取、直接存取、随机存取、相联存取的区别
  • Java最全面试题->Java主流框架->SpringBoot面试题
  • 多线程初阶(十):定时器 模拟实现
  • Docker安装ocserv教程(效果极佳)
  • Golang | Leetcode Golang题解之第502题IPO