C++ Primer第五版_第十三章习题答案(11~20)
文章目录
-
-
- 练习13.11
- 练习13.12
- 练习13.13
- 练习13.14
- 练习13.15
- 练习13.16
- 练习13.17
- 练习13.18
- 练习13.19
- 练习13.20
-
练习13.11
为前面练习中的 HasPtr 类添加一个析构函数。
#ifndef ex13_11_h
#define ex13_11_h#include <string>class HasPtr
{
public:HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0) {}HasPtr(const HasPtr &hp) : ps(new std::string(*hp.ps)), i(hp.i) {}HasPtr& operator=(const HasPtr &hp){std::string *new_ps = new std::string(*hp.ps);delete ps;ps = new_ps;i = hp.i;return *this;}~HasPtr(){delete ps;}
private:std::string *ps;int i;
};#endif // !ex13_11_h
练习13.12
在下面的代码片段中会发生几次析构函数调用?
bool fcn(const Sales_data *trans, Sales_data accum)
{Sales_data item1(*trans), item2(accum);return item1.isbn() != item2.isbn();
}
三次,分别是 accum、item1和item2。
练习13.13
struct X {X() {std::cout << "X()" << std::endl;}X(const X&) {std::cout << "X(const X&)" << std::endl;}
}
给 X 添加拷贝赋值运算符和析构函数,并编写一个程序以不同的方式使用 X 的对象:将它们作为非引用参数传递;动态分配它们;将它们存放于容器中;诸如此类。观察程序的输出,直到你确认理解了什么时候会使用拷贝控制成员,以及为什么会使用它们。当你观察程序输出时,记住编译器可以略过对拷贝构造函数的调用。
练习13.14
假定 numbered 是一个类,它有一个默认构造函数,能为每个对象生成一个唯一的序号,保存在名为 mysn 的数据成员中。假定 numbered 使用合成的拷贝控制成员,并给定如下函数:
void f (numbered s) { cout << s.mysn < endl; }
则下面代码输出什么内容?
numbered a, b = a, c = b;
f(a); f(b); f(c);
输出3个完全一样的数。
练习13.15
假定numbered 定义了一个拷贝构造函数,能生成一个新的序列号。这会改变上一题中调用的输出结果吗?如果会改变,为什么?新的输出结果是什么?
会输出3个不同的数。并且这3个数并不是a、b、c当中的数。
练习13.16
如果 f 中的参数是 const numbered&,将会怎样?这会改变输出结果吗?如果会改变,为什么?新的输出结果是什么?
会输出 a、b、c的数。
练习13.17
分别编写前三题中所描述的 numbered 和 f,验证你是否正确预测了输出结果。
//13.14
#include <iostream>class numbered
{
public:numbered(){mysn = unique++;}int mysn;static int unique;
};int numbered::unique = 10;void f(numbered s)
{std::cout << s.mysn << std::endl;
}int main()
{numbered a, b = a, c = b;f(a);f(b);f(c);
}//13.15
#include <iostream>class numbered {
public:numbered() {mysn = unique++;}numbered(const numbered& n){mysn = unique++;}int mysn;static int unique;
};int numbered::unique = 10;void f(numbered s) {std::cout << s.mysn << std::endl;
}int main()
{numbered a, b = a, c = b;f(a);f(b);f(c);
}//13.16
#include <iostream>class numbered
{
public:numbered(){mysn = unique++;}numbered(const numbered& n){mysn = unique++;}int mysn;static int unique;
};int numbered::unique = 10;void f(const numbered& s)
{std::cout << s.mysn << std::endl;
}int main()
{numbered a, b = a, c = b;f(a);f(b);f(c);
}
练习13.18
定义一个 Employee 类,它包含雇员的姓名和唯一的雇员证号。为这个类定义默认构造函数,以及接受一个表示雇员姓名的 string 的构造函数。每个构造函数应该通过递增一个 static 数据成员来生成一个唯一的证号。
#ifndef ex13_18_h
#define ex13_18_h#include <string>
using std::string;class Employee
{
public:Employee();Employee(const string& name);const int id() const { return id_; }private:string name_;int id_;static int s_increment;
};int Employee::s_increment = 0;
Employee::Employee()
{id_ = s_increment++;
}Employee::Employee(const string& name)
{id_ = s_increment++;name_ = name;
}#endif
练习13.19
你的 Employee 类需要定义它自己的拷贝控制成员吗?如果需要,为什么?如果不需要,为什么?实现你认为 Employee 需要的拷贝控制成员。
#ifndef ex13_19_h
#define ex13_19_h#include <string>
using std::string;class Employee
{
public:Employee();Employee(const string &name);Employee(const Employee&) = delete;Employee& operator=(const Employee&) = delete;const int id() const { return id_; }private:string name_;int id_;static int s_increment;
};#endif
练习13.20
解释当我们拷贝、赋值或销毁 TextQuery 和 QueryResult 类对象时会发生什么?
成员会被复制。