首页 > 编程 > C++ > 正文

C++Primer第五版 第十二章习题答案(1~10)

2019-11-06 08:21:42
字体:
来源:转载
供稿:网友

1:知识点1:对象生命周期:全局对象在程序启动时分配,在程序结束时销毁。局部自动对象,当我们进入其定义所在程序块时被创建,在离开块时被销毁。局部static对象在第一次使用前分配,在程序结束时销毁

知识点2:除了static和自动对象外,C++还支持动态对象的分配。动态分配的对象的生存期与它们在哪里创建无关,只有被显示的释放时,这些对象才会被销毁

知识点3:动态对象的释放是编程中极其容易出问题的地方,为了安全使用动态对象,标准库定义了两个智能指针类型来管理动态分配对象,当一个对象应该被释放时,指向它的智能指针可以确保自动释放它

知识点4:静态内存:保存局部static对象、类static对象、定义在任何函数之外的对象,由编译器自动创建和销毁。栈内存:保存定义在函数之内的非static对象,栈对象仅在定义的程序块运行时才存在

知识点5:除了静态内存和栈内存,每个程序还拥有一个内存池,这部分内存被称为自由空间或堆,程序用堆来存储动态分配的对象:在程序运行时分配的对象,其生存周期由程序来控制,也就是说,当动态对象不再使用时,我们必须显式的销毁:必须正确的管理动态内存

知识点6:C++中动态内存的管理是通过一对运算符来完成的,new:在动态内存中为对象分配空间并返回一个指向该对象的指针。delete:接受一个动态对象的指针,销毁该对象,并释放与之关联的内存

知识点7:忘记释放内存:内存泄漏,在尚有指针引用内存的情况下释放了内存,就会产生引用非法内存的指针

知识点8:为了更安全的使用动态内存,新标准库定义了两种智能指针类型来管理动态对象,头文件为memory,智能指针的主要作用就是自动释放所指向的对象,shared_ptr类型允许多个指针指向同一对象,unique_ptr类型则独占所指向对象

知识点9:智能指针类似与vector,用法上有相同的地方,下面是shared_ptr的定义方式

shared_ptr<string> p1;//定义一个智能指针,指向对象为string类型shared_ptr<list<int>> p2;vector<string> p1;//智能指针也是模版vector<list<int>> p2;

知识点10:智能指针的使用方式与内置类型指针相似,解引用也是返回所指向对象,若在条件判断中使用,检测其是否为空

知识点11:make_shared()函数:最安全的分配和使用动态内存的方法,此函数在动态内存中分配一个对象并初始化它,返回指向该对象的shared_ptr,头文件为memory

shared_ptr<int> p3 = make_shared<int>(42);//p3为智能指针,指向一个值为42的对象auto p3 = make_shared<int>(42);//利用auto比较简便,若不传递任何参数,会值初始化

知识点12:每个shared_ptr都有一个关联的计数器,称为引用计数,个人理解就是该对象被引用的次数,拷贝情况下会递增:

1:用一个shared_ptr初始化另一个shared_ptr(拷贝)

2:将一个shared_ptr传递给一个函数当参数,值传递(拷贝)

3:作为函数的返回值,(返回的是自身的拷贝,也就是活引用的次数+1)

计数器递减情况:

1:给shared_ptr赋予一个新值(也就是说自身指向了另外一个地址,原来指向的对象已经没有引用者,则会自动释放)

2:一个shared_ptr离开其作用域时,会被销毁(递减)

当一个shared_ptr的计数器变为0,他就会自动释放自己所管理的对象,前提是其指向的对象只有一个引用者。

知识点13:当指向一个对象的最后一个shared_ptr被销毁时,该对象会被自动销毁:利用析构函数,会递减该对象的引用计数,当引用次数变为0,会销毁该对象

知识点14:相关联内存是否销毁:所有指向该内存的shared_ptr对象都被销毁,也就是计数器为0

知识点15:使用动态内存的原因:让多个对象共享相同的底层数据。也就是说拷贝的情况虽然发生,但是并不是元素的拷贝,而是将本身的指向拷贝给另一个指针对象,让这一个对象也指向自己所指向的对象,这样在本身释放以后,还有另一个对象指向自身原来所指向的对象。

由知识点15:b1和b2都包含4个元素。

2:直接在函数返回类型之前加const即可~

3:是否要定义为const版本取决于是否需要加以修改,这两个函数都不会对参数进行修改,所以无需加const

4:因为data_size的类型为size_type,是一个无符号类型,即使是负数,也会自动转化为非负。

5:explicit的作用就是抑制构造函数的隐式转换

优点:不会自动的进行类型转换,必须清楚的知道类类型

缺点:必须用构造函数显示创建一个对象,不够方便简单

6:知识点1:new和delete相对于智能指针来说非常容易出错,最好使用智能指针来管理动态内存

知识点2:在自由空间分配的内存是无名的,因此new无法为其分配对象命名,而是返回指向该对象的指针

知识点3:默认情况下,new分配的对象是默认初始化的,这就说明内置类型或者组合类型将是为定义的(l例如:int,会指向一个为初始化的int),类类型对象将用默认构造函数进行初始化(例如string,会产生一个空string)。

知识点4:建议使用值初始化(在最后加一对小括号即可),值初始化的内置类型对象有着良好定义的值

知识点5:auto只有单一参数时可以使用,可以使用new分配const对象

知识点6:delete完成两个操作:销毁给定指针所指向的对象,释放对应的内存,delete的参数必须是指向动态分配的对象或是一个空指针。

知识点7:内置类型指针管理的动态内存在被显式的释放前一直都会存在,因为内置类型与类类型不同,虽然内置类型的指针会在离开作用域后被销毁,但是其内存依然存在

知识点8:同一块内存释放两次:两个内置类型的指针指向同一块自由空间分配的内存,在对一个指针进行delete之后,其指向的内存也会被释放,若再对第二个指针进行delete,会造成自由空间破坏

知识点9:忘记使用delete,使用已经释放掉的对象都是经常发生的(使用new和delete时),所以尽可能的使用智能指针

知识点10:在很多机器上,即使delete了某个内置类型的指针(也就是说释放了对应的内存空间),虽然指针已经无效,但是其仍然保留这释放空间的对应地址,变成了空悬指针,也就是说我们要保留指针,可以将其置为空指针

7:智能指针的版本只是不需要在程序结束时进行delete操作

#include <iostream>  #include <string>  #include <vector>#include<memory>#include<list>using namespace std;  //返回一个动态分配的vector,看第六题的意思是不用只能指针,那么将类型改为vector<int> *就好了shared_ptr<vector<int>> vector_i(){		shared_ptr<vector<int>> _ptr(new vector<int>);	return _ptr;}//给vector赋值void vector_j(shared_ptr<vector<int>> _ptr){	int int_val;	while (cin>>int_val)	{		_ptr->push_back(int_val);	}}//打印vector的值void vector_k(shared_ptr<vector<int>> _ptr){	for (size_t i = 0; i < (*_ptr).size(); ++i)	{		cout<<(*_ptr)[i]<<endl;	}}int main(int argc,char **argv)  {	shared_ptr<vector<int>> my_ptr = vector_i();	vector_j(my_ptr);	vector_k(my_ptr);	return 0;}  

8:p是一个内置类型的指针,返回p会使得p的类型转化为bool类型,其指向的动态内存空间将无法得到释放

9:q,r为内置类型指针,保存动态内存的地址,进行二次赋值之后,r原来指向的内存空间将得不到释放,造成内存泄漏

q2,r2为智能指针,r2进行赋值之后,其计数器将减一,由于r2是指向该内存空间的唯一智能指针,所以该内存会得到释放

10:正确无误


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选