本文主要是介绍13.1.3,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
练习13.9
①析构函数是什么?
②合成析构函数完成什么工作?
③什么时候会生成合成析构函数?
解答:
①析构函数执行与构造函数相反的操作:构造函数初始化对象的非static数据成员,还可能做一些其他工作;析构函数释放对象使用的资源,并销毁对象的非static数据对象。
②其实就和析构函数完成的工作是一样的
③当一个类没有定义自己的析构函数的时候,编译器会为它定义一个合成析构函数。
练习13.10
当一个StrBlob对象销毁时会发生什么?一个StrBlobPtr对象销毁时呢?
解答:
这里可以参考析构函数完成什么工作。
在一个构造函数中,成员的初始化是在函数体执行之前完成的,且按照他们再类中出现的顺序进行初始化。再一个析构函数中,首先执行函数体,然后销毁成员。成员按照初始化顺序的逆序销毁。
练习13.11
在前面练习中的HasPtr类添加一个析构函数。
解答:
#include <iostream>
#include <string>using namespace std;class HasPtr{
public:HasPtr(const string &s = string()):ps(new string(s)), i(0){}//HasPtr(const HasPtr& ori):ps(new string(*(ori.ps))), i(ori.i){};HasPtr& operator=(const HasPtr& ori){ps = new string(*(ori.ps));i = ori.i;return *this;}~HasPtr(){ // 添加析构函数delete ps;}
//private:string *ps;int i;
};int main(){HasPtr a("test string");cout << a.ps << endl;cout << *(a.ps) << endl;HasPtr b;b = a;//HasPtr b(a);cout << b.ps << endl;cout << *(b.ps) << endl;
}
练习13.12
在下面的代码片段中会发生几次析构函数调用?
bool fcn(const Sales_data *trans, Sales_data accum){Sales_data item1(*trans), item2(accum);return item1.isbn() != item2.isbn();}
解答:
这里可以用一段代码进行替换,来更好的了解
include <iostream>using namespace std;class A{public:A():a(10){}~A(){cout << "~A()" <<endl;}int a;
};bool fcn(const A *trans, A accum){A item1(*trans), item2(accum);return item1.a != item2.a;
}int main(){A ori1;A ori2;ori2.a = 9;cout << "function begin" << endl;cout << fcn(&ori1, ori2) << endl;cout << "function end" << endl;
}
在begin和end之中有3次析构函数的调用。
这里分别是,
函数第二个参数复制的对象,函数体中构造的两个对象。
这里要注意,当指向一个对象的引用或指针离开作用域时,析构函数不会执行。
练习13.13
理解拷贝控制成员和构造函数的一个好方法是定义一个简单的类,该类定义这些成员,每个成员都打印出自己的名字:
struct X{X() {std::cout << "X()" << std::endl;}X(const X&) {std::cout << "X(const X&)"<<std::endl;}};
给X添加拷贝复制运算符和析构函数,并编写一个程序以不同方式使用X的对象:将它们作为非引用和引用参数传递;
动态分配它们;将它们存放于容器中;诸如此类。观察程序的输出,直到你确认理解了什么时候会使用拷贝控制成员,以及为什么会使用它们。
当你观察程序输出时,记住编译器可以略过拷贝构造函数的调用。
解答:
这道题的意思很明确,要对编译器的行为进行观察。
#include <iostream>
#include <string>
using namespace std;
struct X{
<span style="white-space:pre"> </span>X() { cout << "X()" << endl; }
<span style="white-space:pre"> </span>X(const X&) { cout << "X(const X&)" << endl; }
<span style="white-space:pre"> </span>X& operator=(const X&) { cout << "operator = ()" << endl; return *this; }
<span style="white-space:pre"> </span>~X() { cout << "~X()" << endl; }
};
int main()
{
<span style="white-space:pre"> </span>X x1;
<span style="white-space:pre"> </span>X x2(x1);
<span style="white-space:pre"> </span>X x3 = x1;
<span style="white-space:pre"> </span>X x4;
<span style="white-space:pre"> </span>x4 = x1;
}
结果表明:
当使用()或者= 进行初始化时,调用的是拷贝构造函数。
当且仅当,先声明X类,在进行拷贝,才调用重载的=运算。
这篇关于13.1.3的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!