《C++代码设计与重用》——1.6 练习

1.6 练习

C++代码设计与重用
1.6 练习
在整本书里,困难的题目将会在题号后面标示(),特别困难的题目会用(*)标示。

1.1 假设你在实现一个函数,这个函数在一个给定的数组中查找某个给定的值。

a.在什么情况使用函数时,线性查找的实现比二分查找的实现具有更高的效率。

b.为了能在任何环境下,你的查找算法都可以更加高效地执行,你应该如何(使用什么算法)实现这个函数呢?

c.假设在这里,我们并不是查找用户给定的值,而是查找第一个0出现的位置,那么需要在什么样的条件下,线性查找才能比二叉查找更有效呢?

d.假设我们现在的查找范围不再是用户给出的数组,而是一个具体的数组,但查找值仍然是用户指定的。假设函数is_prime为了判断某个小于1000的数字是否是素数,需要查找一组所有小于1000的素数。那么,以这个假设为前提,在什么样的条件下,线性查找才能比二叉查找具有更高的效率?

1.2 在这个练习和下面的练习里,我们将分析一个问题,它是由程序库设计者未能在开初就显式声明程序库的用户类型而引起的。

假设我们是可重用类Path的设计者,其中Path表示我们用户文件系统中的路径名称。例如,在UNIX系统中,典型的路径有:dir、dir/dir2/tmp和../tmp等;在Windows系统中,相应的路径应该写成:dir、dirdir2tmp和..tmp;而在VMS系统中,这些相应的路径为:dir、[dir.dir2]tmp和[-]tmp。

假设当我们开始设计Path时,我们忘记了指定这个类的用户类型;那么,在设计过程中途,如果我们是UNIX程序员,我们可能就只会以UNIX路径的模式来设计Path:

class Path {
    public:
         Path();
         Path(const String& s);
         //...
    private:
         void canonicalize();
    };

上面的代码中,缺省构造函数创建了一个空路径,另一个构造函数创建了一个规范形式的路径s。在规范形式里,.标志符已经被删除,..标志符也尽可能被去掉,多个连续的/被精减为单个/,剩下的/都删除掉了。于是,例如下面字符串

../../dir/./dir2//other_dir/..tem.c/

的规范形式是:

../../dir/dir2/tem.c

a.(*)如果用户让Path的构造函数自动规范化所给的字符串,那么对于什么样的UNIX系统用户,才会出现不可取的行为?(提示:何时dir/../some_file/和some_file表示不同的文件?)

b.对于Windows用户而言,为什么第二个构造函数的行为是错误的呢?

1.3 为了能够同时适应Windows系统程序员和UNIX系统程序员,我们可以改变Path类的设计,让用户指定作为路径分隔符的字符:

class Path {
    public;
         Path(const String& s, char separator);
         //...
    };

于是,UNIX系统上的用户必须指定‘/’为分隔符,而Windows用户必须指定‘’(这实际上是一个转义后的反斜杠符)分隔符。那么这个改变会给现在的UNIX用户带来什么样的问题呢?你是否可以在避免这种问题发生的前提下,改变Path类的设计呢?

1.4 假设我们现在希望为VMS用户提供Path类。在VMS系统中,没有特殊的字符被认为是路径分隔符;于是,练习1.3设计的Path接口并不适用于VMS的用户。为了改善Path的设计,我们必须再次改变Path的实现:

class Path {
    public:
         enum Style { UNIX, Windows, VMS};
         Path(const String& s, Style style = UNIX);
         //...
    };

那么对于当前的UNIX用户和Windows用户,这个改变会导致什么样的问题呢?

1.5 给出设计下面4个类的方法:Paht、Unix_path、Windows_path和Vms_path,后面3个类派生自第1个类,并且用户可以如下编写代码:

Vms_path r("[dir]tmp");
    Unix_path p("/dir/tmp");
    Windows_path q("\\dir\\tmp");

假设不存在早期版本的Path类的用户,那么与练习1.4的设计相比,请给出这个设计的一个缺点和一个优点。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

时间: 2024-08-02 07:42:46

《C++代码设计与重用》——1.6 练习的相关文章

《C++代码设计与重用》导读

前言 C++代码设计与重用 一切事物都将得到检验并因此被称为问题. Edith Hamilton 这本书的主要目的在于:展示如何以C++编程语言编写可重用代码-就是说,根据不同的需要,在不经过修改,或者经过很少修改的前提下,可重用代码可以很容易地应用到5个.50个甚至500个程序当中,而且这些程序往往是不同程序员编写的,可能运行在不同的系统上.在整个阐述的过程中,我们的目的并不在于争论是否所有的代码都是可重用的,也不在于说明可重用代码能够解决所有的程序问题.显然,不论是对程序员而言,还是对可重用

《C++代码设计与重用》——2.3 Nice类

2.3 Nice类 C++代码设计与重用 2.3 Nice类 我们都知道类会提供某些函数,这些函数要么是在类的代码中被显式声明为公共的(public)或保护的(protected),要么是由编译器在程序需要这些代码时隐式生成的.例如,下面这个类: class X{ public: X(); void f(); }; 它提供了一个缺省构造函数.函数f.一个拷贝构造函数.一个赋值运算符和一个析构函数.而且最后3个函数会在程序需要它们的时候由编译器自动生成. 请考虑下面这个通常有用的函数: templ

《C++代码设计与重用》——1.5 这本书能给我们带来什么

1.5 这本书能给我们带来什么 C++代码设计与重用 1.5 这本书能给我们带来什么 编写可重用代码可以使复杂的问题变得比较简单,但编码过程是非常困难的.这本书不会也不能让这困难的过程变得格外简单,这本书也没有提供能让每个C++程序员都可以很轻松地编写出可重用代码的锦囊妙计. 针对每个希望编写出可重用代码的C++程序员,这本书的每一章都讨论了一个或者多个他们必须理解的问题.理解了这些问题虽然不能使编写可重用代码变得相当简单,但可以让编写出可重用代码成为一种可能. 这本书的其余部分的结构如下: 当

《C++代码设计与重用》——1.2 重用的神话

1.2 重用的神话 C++代码设计与重用1.2 重用的神话关于代码重用出现了许多神话(荒诞的说法),这一节我们来反驳几个比较普遍的说法. 神话1:重用可以解决软件危机 软件危机是指程序设计团体现今没有能力做到以下几点:编写解决复杂问题的程序,快速生成解决复杂问题的程序,正确编写这些程序并使这些程序的维护相当容易. 软件开发进步的迹象是显而易见的.一个很显然的迹象就是随着时间的推移,所谓的复杂问题的范围发生了改变.在20世纪60年代,编写一个FORTRAN-66编译器就被认为是一个非常复杂的问题:

《C++代码设计与重用》——1.1 什么是重用性

1.1 什么是重用性 C++代码设计与重用 1.1 什么是重用性 许多相同操作都会在多个计算机程序里重复实现,例如: 对数组元素进行排序:解答线性方程组:实现一个从X类型到Y类型的映射:解析C++代码:从数据库检索数据:和其他程序进行通信.与其在每个程序里都设计和实现上面每个操作的相同代码,我们更愿意采用的方法是:只设计和实现这些操作的代码一次,然后再把这些代码重用手不同程序里.显然,已有的可重用代码,使每个应用程序不必从头写起,因为它(可重用代码)大大加速了应用程序的开发,并且减少了编写和维护

《C++代码设计与重用》——2.7 转型

2.7 转型 C++代码设计与重用2.7 转型程序库设计者必须充分重视隐式转型(implicit conversion).在C++中,有两种方法可以用来定义从类型From到类型To的隐式转型.第一种,我们可以在类To中定义一个只含一个参数的构造函数(并且没有其他的缺省参数): class To { public: To(const From&); //或者是To(From) //... }; 或者,我们可以在类From中定义一个转型操作: class From { public: operato

《C++代码设计与重用》——2.9 总结

2.9 总结 C++代码设计与重用2.9 总结正规函数-拷贝构造函奴.析构函数.基本赋值运算符.相等运算符和不等运算符-在所有的类中都应该实现相同的语义. 尽管没有最小标准接口,但是nice函数-缺省构造函数.拷贝构造函数.赋值运算符和相等运算符-应该是大多数类都提供的函数.没有任何函数是所有的类都应该提供的函数:而且,绝大多数类都不应该提供浅拷贝和深拷贝操作. 对程序库中类的接口一致性,我们应该给予充分的重视.但是当一致性使类的接口变得很不适当或者不直观时,我们就不能一味顽固地坚持这种一致性.

《C++代码设计与重用》——2.2 正规函数

2.2 正规函数 C++代码设计与重用2.2 正规函数对所有提供它们的类而言,某些函数应该具有相同的语义.考虑类Rational的拷贝构造函数: class Rational { public: Rational(const Rational& r); //... }; 上面的操作将会构造一个Rational对象,它的值等同于对象r的值(我们所说的值总是指抽象值).我们认为,每个类的拷贝构造函数都应该具有这样的语义,就是构造一个和它的参数等值的对象.尽管C++没有-也不能-强制拷贝构造函数遵循这

《C++代码设计与重用》——2.5 浅拷贝和深拷贝

2.5 浅拷贝和深拷贝 C++代码设计与重用2.5 浅拷贝和深拷贝有两个操作,尽管它们具有某些不合乎需要的特性,但因为它们的使用范围很广,进而博得一定的注意,所以这两个操作在这里有必要特别提及一下,这两个操作就是浅拷贝操作和深拷贝操作.x对象的浅拷贝是指:另一个和x相同类型的,并且它的数据成员和x相对应的数据成员具有相同值的对象.x对象的深拷贝是指:另一个和x类型相同的对象,它具有x直接或间接指向的对象的一份拷贝,并且在拷贝里,所有共享和循环的联系依旧保留.考虑下面3个类: class Z {

《C++代码设计与重用》——第1章 重用性介绍

第1章 重用性介绍 C++代码设计与重用程序库是聪明的程序员最好的咨询室. -George Dawson 在介绍重用性的这一章里,我们先描述什么是重用性,其中特别着重讨论代码提取技术.因为代码(仅供参考)提取是重用的原始形式,也正是它的不足促使我们对可重用代码下定义.接着我们反驳一些有关重用性的神话(对重用性错误的理解),并列举了阻碍重用性发展的障碍-技术性的和非技术性的.最后,我们对有志于编写可重用代码的程序员提出若干期望. 本文仅用于学习和交流目的,不代表异步社区观点.非商业转载请注明作译者