且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《C++编程惯用法——高级程序员常用方法和技巧》——2.11 问题

更新时间:2022-09-18 12:25:20

本节书摘来自异步社区出版社《C++编程惯用法——高级程序员常用方法和技巧》一书中的第2章,第2.11节,作者: 【美】Robert B. Murray ,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.11 问题

1.复制构造函数X::X(X)在C++中是非法的。请解释其原因。

2.我们的String类的构造函数通过调用

new char[strlen(cp)+1];

来为它的数据获取存储空间。不过在字符串中只有strlen(cp)个字符,那么多出来的那个字符是做什么用的呢?

3.我们的File类假设所有的File对象都表示一个唯一的文件描述符——对一个File进行复制会产生一个新的描述符。假设我们希望复制一个File对象时只产生一个和该对象共享已有描述符的对象——也就是说这个新的对象不会对已有描述符的数目进行递增。我们应该如何修改File类来达到这个目的呢?(提示:仅仅不让复制构造函数去修改那个计数器是不够的。)

4.一个编译器制造商可能是为了节省开发成本,没有去实现内嵌的展开:也就是说,所有的对于内嵌函数的调用都会被解释为一次真正的函数调用。对于C++来说,这样做是合法的,但对于使用该编译器的用户来说,这样做可能会是一场灾难。为什么?

5.有个程序员可能希望为double和Rational的任意组合提供一个加法操作符。请为他提出两种解决方案,并对它们的优缺点做出评价。

6.向上题中的加法操作增添对Complex的支持并重复上题中的讨论。

7.为我们已有的Complex类(使用了极坐标表示)实现设置其(笛卡儿坐标系中的)实部和虚部的函数。

8.我们的Complex类中用来设置其实部和虚部的函数的返回值是void。我们可以把它们的返回值改成什么样才有意义呢?是否存在着其他的答案可以使得问题更加清楚?如果没有的话,你会建议使用哪种方法呢?

9.假设我们正在使用String类,它提供了一个operator const char*的转换函数:

class String {
public:
   operator const char*() const;
   //此处忽略细节
};

再假设我们有一个函数remove_blanks,它带有一个类型为char*的参数,我们用它来去除它的参数所指向的字符串中的空格:

void
remove_blanks (char* cp){
   char* p = cp;
   while(*p) {
     if (*p != ' ')
        *cp++ = *p;
     ++p;
   }
   *cp = '\0';
}

最后假设有个用户,他试图用这个函数来去除掉一个String对象中的所有空格,为的是将这个String对象变短,而不是变长:

String s("hello world");
remove_blanks((char*)(const char*)s);

请问他这样做安全吗?为什么?

10.下面的类中有什么错误?

class Node{
//此处忽略细节
public:
   Node();               //叶节点
   Node(const Node&);        //一元
   Node(const Node&, const Node&);  //三元
};

我们应该如何更改它的接口来修正这个问题?

[1]译注:在这作者显得有点乐观,他假设修改类的开发人员会去认真地阅读头文件中的注释,只有在读过头文件中的注释并正确理解其中意义的前提下,我们才可能得到作者所期望得到的结果。

[2]如果我们使用的编译器支持异常,那么它应该抛出一个异常(详见第10章),而不是退出函数。

[3]译注:此处的向量是几何中的向量,而不是像标准库中那样用于表达一个数组的向量。

[4]译注:即va_start、va_list以及va_end。

[5]译注:即所谓的NVO。

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