C++ Primer第五版_第十八章习题答案(11~20)

news/2025/2/14 3:20:19/

文章目录

      • 练习18.11
      • 练习18.12
      • 练习18.13
      • 练习18.14
      • 练习18.15
      • 练习18.16
      • 练习18.17
      • 练习18.18
      • 练习18.19
      • 练习18.20

练习18.11

为什么 what 函数不应该抛出异常?

what中如果抛出异常,需要try catch捕获,再调用what,一直循环,直达内存耗尽。

练习18.12

将你为之前各章练习编写的程序放置在各自的命名空间中。也就是说,命名空间chapter15包含Query程序的代码,命名空间chapter10包含TextQuery的代码;使用这种结构重新编译Query代码实例。

Query.h

#ifndef QUERY_H_
#define QUERY_H_#include <string>
#include <iostream>
#include "Query_base.h"
#include "WordQuery.h"
#include "TextQuery.h"namespace chapter15
{class Query{friend Query operator~(const Query&);friend Query operator|(const Query&, const Query&);friend Query operator&(const Query&, const Query&);public:Query(const std::string&);chapter10::QueryResult eval(const chapter10::TextQuery &t) const { return q->eval(t); }std::string rep() const { std::cout << "Query::rep()" << std::endl; return q->rep(); }private:Query(std::shared_ptr<Query_base> query) : q(query) { std::cout << "Query(std::shared_ptr<Query_base> query)" << std::endl; }std::shared_ptr<Query_base> q;};std::ostream& operator<<(std::ostream &os, const Query &query){return os << query.rep();}inline Query::Query(const std::string &s) : q(new WordQuery(s)) { std::cout << "Query::Query(const std::string &s)" << std::endl; }
}#endif

TextQuery.h

#ifndef TEXTQUERY_H_
#define TEXTQUERY_H_#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <sstream>
#include <set>
#include <memory>
#include <iostream>
#include <algorithm>
#include <iterator>
#include "StrBlob.h"namespace chapter10
{class QueryResult;class TextQuery{public:using line_no = std::vector<std::string>::size_type;TextQuery(std::ifstream&);QueryResult query(const std::string&) const;private:StrBlob file;std::map<std::string, std::shared_ptr<std::set<line_no>>> word_map;};class QueryResult{friend std::ostream& print(std::ostream&, const QueryResult&);public:QueryResult(std::string s, std::shared_ptr<std::set<TextQuery::line_no>> p, StrBlob f) : sought(s), lines(p), file(f) { }std::set<StrBlob::size_type>::iterator begin() const { return lines->begin(); }std::set<StrBlob::size_type>::iterator end() const { return lines->end(); }// std::shared_ptr<StrBlob> get_file() const { return std::make_shared<StrBlob>(file); }const StrBlob& get_file() const { return file; }private:std::string sought;std::shared_ptr<std::set<TextQuery::line_no>> lines;StrBlob file;};TextQuery::TextQuery(std::ifstream &ifs){std::string text_line;while(std::getline(ifs, text_line)){file.push_back(text_line);int line_number = file.size() - 1;std::istringstream line(text_line);std::string text_word;while(line >> text_word){std::string word;std::copy_if(text_word.begin(), text_word.end(), std::back_inserter(word), isalpha);// std::cout << word << std::endl;auto &wm_lines = word_map[word];if(!wm_lines)wm_lines.reset(new std::set<line_no>);wm_lines->insert(line_number);}}}QueryResult TextQuery::query(const std::string &sought) const{static std::shared_ptr<std::set<TextQuery::line_no>> nodata(new std::set<TextQuery::line_no>);auto loc = word_map.find(sought);if(loc == word_map.end())return QueryResult(sought, nodata, file);elsereturn QueryResult(sought, loc->second, file);}std::ostream &print(std::ostream &os, const QueryResult &qr){os << qr.sought << " occurs " << qr.lines->size() << " " /*<< make_plural(qr.lines->size(), "time", "s")*/ << std::endl;for(auto num : *qr.lines){ConstStrBlobPtr p(qr.file, num);os << "\t(line " << num + 1 << ") " << p.deref() << std::endl;}return os;}
}#endif

练习18.13

什么时候应该使用未命名的命名空间?

在需要在其所在的文件中可见,在其所在的文件外不可见时;
static只能用于变量与函数,不可用于用户自定义的类型。

练习18.14

假设下面的operator*声明的是嵌套的命名空间 mathLib::MatrixLib 的一个成员:

namespace mathLib {namespace MatrixLib {class matrix { /* ... */ };matrix operator* (const matrix &, const matrix &);// ...}
}

请问你应该如何在全局作用域中声明该运算符?

mathLib::MatrixLib::matrix mathLib::MatrixLib::operator*(const matrix&, const matrix&);

练习18.15

说明 using 指示与 using 声明的区别。

using指示引入的名字的作用域远比using声明引入的名字的作用域复杂。它具有将命名空间成员提升到包含命名空间本身和using指示的最近作用域的能力。对于using声明来说,我们指示简单地领名字在局部作用域有效。

using指示是令整个命名空间的所有内容变得有效。通常情况下,命名空间中会含有一些不能出现在局部作用域的定义,因此using指示一般被看作是出现在最近的外层作用域中。

练习18.16

假定在下面的代码中标记为“位置1”的地方是对命名空间 Exercise中所有成员的using声明,请解释代码的含义。如果这些using声明出现在“位置2”又会怎样呢?将using声明变为using指示,重新回答之前的问题。

namespace Exercise {int ivar = 0;double dvar = 0;const int limit = 1000;
}
int ivar = 0;
//位置1
void main() {//位置2double dvar = 3.1416;int iobj = limit + 1;++ivar;++::ivar;
}
namespace Exercise{int ivar = 0;double dvar = 0;const int limit = 1000;
}
int ivar = 0;using Exercise::ivar;	//1
using Exercise::dvar;
using Exercise::limit;// using namespace Exercise;	//3void mainp(){// using Exercise::ivar;	//2// using Exercise::dvar;// using Exercise::limit;// using namespace Exercise;	//4double dvar = 3.1416;int iobj = limit + 1;++ivar;++::ivar;
}int main()
{return 0;
}

练习18.17

实际编写代码检验你对上一题的回答是否正确。

练习18.18

已知有下面的 swap 的典型定义,当 mem1 是一个 string 时程序使用 swap 的哪个版本?如果 mem1 是 int 呢?说明在这两种情况下名字查找的过程。

void swap(T v1, T v2)
{using std::swap;swap(v1.mem1, v2.mem1);//交换类型的其他成员
}

前者使用string版本的swap;后者使用实例化为int的swap。

练习18.19

如果对 swap 的调用形如 std::swap(v1.mem1, v2.mem1) 将会发生什么情况?

将只使用标准库的swap,如果v1.mem1和v2.mem1为用户自定义类型,将无法使用用户定义的针对该类型的swap。

练习18.20

在下面的代码中,确定哪个函数与compute调用匹配。列出所有候选函数和可行函数,对于每个可行函数的实参与形参的匹配过程来说,发生了哪种类型转换?

namespace primerLib {void compute();void compute(const void *);
}
using primerLib::compute;
void compute(int);
void compute(double, double = 3.4);
void compute(char*, char* = 0);
void f()
{compute(0);
}

候选函数:全部;
可行函数:
void compute(int)(最佳匹配)
void compute(double, double = 3.4)(int->double)
void compute(char*, char* = 0)(0->nullptr)
void compute(const void *)(0->nullptr)
改变后:
void compute(const void *)为最佳匹配。


http://www.ppmy.cn/news/90543.html

相关文章

霍尔电流传感器的注意事项及其在直流列头柜中的应用

安科瑞虞佳豪 霍尔电流传感器​注意事项 &#xff08;1&#xff09;电流传感器必须根据被测电流的额定有效值适当选用不同的规格的产品。被测电流长时间超额&#xff0c;会损坏末极功放管&#xff08;指磁补偿式&#xff09;&#xff0c;一般情况下&#xff0c;2倍的过载电流…

“多杆合一”降本增效——数字孪生智慧灯杆

随着智慧城市建设的不断深入&#xff0c;智慧灯杆作为城市基础设施的重要组成部分&#xff0c;正在成为城市智能化和绿色化的重要手段之一。 图扑智慧灯杆系统在城市道路照明领域引入信息化手段&#xff0c;通过构建路灯物联网&#xff0c;实现了现代化的路灯按需维修和按需照…

【操作系统真象还原】第4章:保护模式入门(4.4~4.5节)

目录 4.4 处理器微架构简介 4.4.1 流水线 4.4.2 乱序执行 4.4.3 缓存 4.4.4 分支预测 4.5 使用远跳转指令清空流水线&#xff0c;更新段描述符缓冲寄存器 4.6 保护模式之内存段的保护 4.6.1 向段寄存器加载选择子时的保护 4.6.2 代码段和数据段的保护 4.6.3 栈段的保…

Rust 入门教程

文章目录 前言1. 使用cargo创建项目2. 编程语言类型1. 整数2. 浮点数3. 字符 3. 常量与不可变变量的区别4. 重影&#xff08;Shadowing&#xff09;5. 两个重要的泛型类型6. 常见的内存管理方式7. 如何理解生命周期&#xff1f;8. 条件语句1. if实例2. while循环实例3. for循环…

【Linux】关于OOM(Out of Memory)相关的介绍及处理方法

关于OOM(Out of Memory)相关的介绍及处理方法 OOM&#xff08;Out-of-Memory&#xff09;机制是内核的一部分&#xff0c;用于处理内存消耗过度的情况。OOM机制的责任是选择一个或多个高内存消耗的进程&#xff0c;并终止它们以释放内存。 在Linux中&#xff0c;进程的OOM Sc…

数据高效转储,生产轻松支撑

在使用WINDOWS或智能手机的时候&#xff0c;经常会遇到存储空间不足的问题&#xff0c;鲜有人会打开文件管理系统自己逐个清理&#xff0c;不仅因为底层的系统文件繁多操作耗时&#xff0c;更有其操作专业度高、风险高的问题。这时我们往往会求助各种各样的清理大师&#xff0c…

组合总和-回溯

1题目 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 示例 1: 输入: k 3, n 7 输出: [[1,2,…

QT软件开发: 获取CPU序列号、硬盘序列号、主板序列号 (采用wmic命令)

一、环境介绍 QT版本: 5.12.6 环境: win10 64位 编译器: MinGW 32 二、功能介绍 通过wmic 命令获取CPU序列号、硬盘序列号、主板序列号、CPU名称等信息。 做软件加密、数据加密、软件1机1码绑定的场合比较实用。 WMIC扩展WMI&#xff08;Windows Management Instrument…