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 

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 

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 

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 

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 
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 
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 类对象时会发生什么?

成员会被复制。

你可能感兴趣的:(C++《i+1》,c++,开发语言)