zoukankan      html  css  js  c++  java
  • 条款19:设计class犹如设计type

    C++就像在其他OOP(面向对象编程语言)一样,当你定义一个新class,也就 定义了一个新type。身为C++程序员,你的许多时间主要用来扩张你的类型系统(type system)。这意味你并不只是class设计者,还是type设计者。重载(overloading)函数和操作符、控制内存的分配和归还、定义对象的初始化和终结…全都在你手上。因此你应该带着和“语言设计者当初设计语言内置类型时”一样的谨慎来研讨class的设计。

    设计优秀的classes是一项艰巨的工作,因为设计好的types是一项艰巨的工作。好的types有自然的语法,直观的语义,以及一或多个高效实现品。在C++中,一个不良规划下的class定义恐怕达到上述任何一个目标。甚至class的成员函数的效率有可能受到他们“如何被声明”的影响。

    (1) 新type的对象应该如何被创建和销毁?

    这会影响到你的class的构造函数和析构函数以及内存分配函数和释放函数(operator new ,operator new[],operator delete和operator delete[]–见第8章)的设计,当然前提是如果你打算撰写它们。

    (2)对象的初始化和对象的赋值该有什么样的差别?

    这个答案决定你的构造函数和赋值(assignment)操作符的行为,以及其间的差异。很重要的是别混淆了“初始化”和“赋值”,因为它们对应于不同的函数调用。

    (3)新type的对象如果被passed by value(以值传递),意味着什么?

    记住,copy构造函数用来定义一个type的pass-by-value该如何实现。

    (4)什么是新type的“合法值”?

    对class的成员变量而言,通常只有某些数值集是有效的。那些数值集决定你的class必须维护的约束条件(invariants),也就决定了你的成员函数(特别是构造函数、赋值操作符合所谓“setter”函数)必须进行的错误检查工作。它也影响函数抛出的异常、以及(极少被使用的)函数异常明细列(exception specifications)。

    (5)你的新type需要配合某个继承图系(inheritance graph)吗?

    如果你继承自某些既有的classes,你就受到那些classes的设计的束缚,特别是收到“它们的函数是virtual 或non-virtual”的影响(见条款34和条款36)。如果你允许其他classes继承你的class,那会影响你所声明的函数-尤其是析构函数-是否为virtual(见条款7)。

    (6)你的新type需要什么样的转换?

    你的type生存与其他types之间,因而彼此该有转换行为吗?如果你希望允许类型T1之物被隐式转换为类型T2之物,就必须在class T1内写一个类型转换函数(operator T2)或在class T2内写一个non-explicit-one-argument(可被单一实参调用)的构造函数。如果你只允许explicit构造函数存在,就得写出专门负责执行转换的函数,且不得为类型转换操作符(type conversion operators)或non-explicit-one-argument构造函数。(条款15有隐式和显示转换函数的范例。)

    (7)什么样的操作符和函数对此新type而言是合理的?

    这个问题的答案决定将为你的class声明哪些函数。其中某些该是member函数,某些则否(见条款23,24,46)。

    (8)什么样的标准函数应该驳回?

    那些正是你必须声明为private者(见条款6)。

    (9)谁该取用新type的成员?

    这个提问可以帮助你决定哪个成员为public,哪个成员为protected,哪个为private.它也帮助你决定哪一个classes 和/或 functions应该是friends,以及将它们嵌套于另一个之内是否合理。

    (10)什么是新type的“未声明接口”(undeclared interface)?

    它对效率、异常安全性(见条款29)以及资源运用(例如多任务锁定和动态内存)提供何种保证?

    你在这些方面提供的保证将为你的class实现代码加上相应的约束条件。

    (11)你的新type有多么一般化?

    或许你其实并非定义一个新type,而是定义一整个types家族。果真如此你就不应该定义一个新class,而是应该定义一个新的class template.

    (12)你真的需要一个新type吗?

    如果只是定义新的derived class以便为既有的class添加机能,那么说不定单纯定义一或多个non-member函数或templates,更能够达到目标。

    这些问题不容易回答,所以定义出高效的classes是一种挑战。然后如果能够设计至少像C++内置类型一样好的用户自定义(user-defined)classes,一切函数便都值得。

  • 相关阅读:
    陶瓷电容的结构、工艺、失效模式
    Vue.js最佳实践
    Vue 超快速学习
    CSS 小技巧
    HTML5 Canvas
    webkit下面的CSS设置滚动条
    Some untracked working tree files would be overwritten by checkout. Please move or remove them before you can checkout. View them
    JSCS: Please specify path to 'JSCS' package
    React中ref的使用方法
    React 60S倒计时
  • 原文地址:https://www.cnblogs.com/lasnitch/p/12764177.html
Copyright © 2011-2022 走看看