您的位置:首页 > 编程语言 > C语言/C++

C++Primer第五版 第七章习题答案(21~30)

2017-02-16 10:35 639 查看
21.22:通常的做法是将相关变量定义为private,而接口函数定义为public。具体情况具体讨论

23:知识点1:类可以自定义某种类型在类中的别名—通过typedef和using

知识点2:如果我们需要合成的默认构造函数,在空列表的构造函数后加上=default即可

知识点3:类的成员也可以重载,参数列表数量或者类型上不同

知识点4:在变量前加关键字mutable,变为可变数据成员,即使是在一个const的对象函数中也可以被修改

知识点5:类内初始值,直接用=赋予的方式是C++11新特性,也就是VS2013以上的版本才支持

知识点6:当某个数据成员在构造函数初始化列表中忽略,它将以默认构造函数的方式隐式初始化

#ifndef Cccc//第一次包含本头文件时,#ifndef判断为真,预处理器将处理后面的内容直到#endif,此时的预处理变量Cccc已定义
#define Cccc//第二次包含本头文件时,#ifndef判断为假,预处理器将忽略后面的内容

#include <string>

class Screen {
public:
using pos = std::string::size_type;//std库中的string类的sizetype类型

Screen() = default;
Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c)
{
}

char get() const { return contents[cursor]; }
char get(pos r, pos c) const { return contents[r * width + c]; }

private:
pos cursor = 0;
pos height = 0, width = 0;
std::string contents;
};

#endif//只要简单的加上就好了,无视C++中的作用域规则,作用是防止头文件被重复包含

/*
c++ string::size_type详解
string::size_type类型
从逻辑上来讲,size()成员函数似乎应该返回整型数值,或如2.2节“建议”中所述的无符号整数。但事实上,size操作返回的是string::size_type类型的值。
我们需要对这种类型做一些解释。string类类型和许多其他库类型都定义了一些伙伴类型(companion types)。这些伙伴类型使得库类型的使用是机器无关的(machine-independent)。
size_type就是这些伙伴类型中的一种。它定义为与unsigned型(unsigned int或unsigned long)具有相同的含义,而且可以保证足够大可存储任意string对象的长度。
为了使用由string类型定义的size_type类型,程序员必须加上作用域操作符来说明所使用的size_type类型是由string类定义的。
任何存储string的size操作结果的变量必须为string::size_type类型。特别重要的是,不要把size的返回值赋给一个int变量。
虽然我们不知道string::size_type的确切类型,但可以知道它是unsigned型(2.1.1节)。对于任意一种给定的数据类型,它的unsigned型所能表示的最大正数值比对应的signed要大一倍。
这个事实表明size_type存储的string长度是int所能存储的两倍。
使用int变量的另一个问题是,有些机器上int变量的表示范围太小,甚至无法存储实际并不长的string对象。如在有16位int型的机器上,int类型变量最大只能表示32767个字符的string对象。
而能容纳一个文件内容的string对象轻易就会超过这个数字。因此,为了避免溢出,保存一个string对象size的最安全的方法就是使用标准库类型string:: size_type。

string类类型和许多其他库类型都定义了一些配套类型(companion type)。通过这些配套类型,库类型的使用就能和机器无关(machine-independent)。string::size_type定义为unsigned型,可以保证足够大的存储string对象的长度。

注意,任何存储string的size操作结果的变量必须为string::size_type类型。尤其不能把size的返回值赋给一个int变量。(因为size返回的是一个unsigned类型,而int是signed类型。size能表达的大小是int的2倍)。

string str("some string");   //通过字符串字面值赋值给串
for (string::size_type ix = 0; ix != str.size(); ++ix)   //此处不该为int     用!=,而不用<=
{
cout<<str[ix]<<endl;
}

vector<int> ivec;
for(vector<int>::iterator ix = ivec.begin(); ix != ivec.end(); ++ix)
//此处不该为int     用!=,而不用<=
{
*ix = 0; //将各个元素赋值为0
}

综上所述:string::size_type 等价于 unsigned ,使用情况为存储字符串的大小
*/


24:

Screen() = default; // 1
Screen(pos ht, pos wd) : height(ht), width(wd), contents(ht * wd, ' ') {} // 2
Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c)
{
} // 3

其他同上

25:只有内置类型和string类型可以依赖于操作的默认版本

26:在类体外定义直接加inline即可,体内声明为inline也可,但要保持一致。

27:知识点:返回引用的函数为左值,返回*this的函数,返回本函数修改后的对象本身而非对象的副本。这样的话就会出现函数的重复使用,如下:

myScreen.move(4, 0).set('#').display(std::cout);
//move()和display()函数可以相互调用,因为他们的返回值是对象的本身,该对象就是myScreen,move()和dispaly()函数对myScerrn执行不同的操作


28:知识点:若函数返回类型变为Screen,则返回的是对象的副本,函数的操作只能添加于对象的副本上,对象的本身并没有改变。

此题中,myScreen本身并不会被三个函数所改变,所以不会输出“#”

29:正确

30:优点:

1:当需要将一个对象作为整体引用而不是引用对象的一个成员时,使用this,则该函数返回对调用该函数的对象的引用。 

2:可以非常明确地指出访问的是调用该函数的对象的成员,且可以在成员函数中使用与数据成员同名的形参。  

缺点:不必要使用,代码多余。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: