primer 5th 12.6练习代码
#include <iostream> #include <algorithm> #include<memory> #include<vector> using std::vector; using std::cin; using std::cout; using std::endl; vector<int>* factory(int i) { ; return new vector<int>{i}; } vector<int>* use_factory(int i) { vector<int>* p=factory(i); for(int ret;cin>>ret;p->push_back(ret)) ; return p; } void use_two_factory(int i) { auto it=use_factory(i); for(const auto& c:*it) cout<<c<<" "; cout<<endl; delete it; it=nullptr; }
/*************************************************************************** * @file The code is for the exercises in C++ Primmer 5th Edition * @author Alan.W * @date 22 DEC 2013 * @remark ***************************************************************************/ //! //! Exercise 12.6: //! Write a function that returns a dynamically allocated vector of ints. //! Pass that vector to another function that reads the standard input to //! give values to the elements. Pass the vector to another function to print //! the values that were read. //! Remember to delete the vector at the appropriate time. //! #include <iostream> #include <vector> #include <string> #include <memory> std::vector<int>* dynamic_vector_generator(); void dynamic_vector_processor(std::vector<int>* ptr_v); void dynamic_vector_printer(std::vector<int>* ptr_v); int main() { /** * testing the 3 functions */ std::vector<int>* ptr_vi = dynamic_vector_generator(); dynamic_vector_processor(ptr_vi); dynamic_vector_printer(ptr_vi); delete ptr_vi; return 0; } /** * @brief return a pointer to dynamicly allocated vector of ints */ std::vector<int>* dynamic_vector_generator() { std::vector<int>* ptr_v = new std::vector<int>(); return ptr_v; } /** * @brief return a pointer to vector of ints * @param ptr_v pointer to vector of ints */ void dynamic_vector_processor(std::vector<int>* ptr_v) { int i; std::cout << "plz enter:\n"; while (std::cin >> i && i != 999) ptr_v->push_back(i); } /** * @brief print the content of the vector that ptr_v points to * @param ptr_v */ void dynamic_vector_printer(std::vector<int>* ptr_v) { for (const auto& e : *ptr_v) std::cout << e << " "; std::cout << "\n"; }
使用new分配内存,delete释放new分配的内存。使用这两个运算符管理内存非常容易出错,自己管理内存的类与使用智能指针的类不同,它们不能依赖类对象拷贝,赋值和销毁操作的默认定义。
1.使用new动态分配和初始化对象:
默认动态分配的对象是默认初始化的,因此内置类型(如int)和组合类型的对象的值将是未定义的,而类类型的对象将由默认构造函数进行初始化:
string *ps=new string; //空string;
int *pi-new int; //Pi指向一个未初始化的int
初始化方式:直接初始化 int *pi=new int(1024);
列表初始化: vector<int> *pv=new vector<int> {0,1,2,3,4,5,6,7,8,9};
进行值初始化(默认),在类型名后面跟一对空括号: int *pi1=new int(); //默认初始化为0;*pi1为0;
使用auto:括号中包含单一初始化器使从此推断我们想要分配的对象的类型。 auto p1=new auto(obj);//p指向与obj相同的对象,该对象用obj进行初始化;p1是指针,obj是string,p1是string*;
2.动态分配的const :
const对象必须进行初始化 const int* pci=new const int(1024);
const string *pcs=new const string;
分配对象是const的,new返回一个指向一个const 的指针。
释放const对象: delete pci;
3.释放动态内存:
delete将动态内存归还给系统。delete p;// p必须指向一个动态分配对象或是一个空指针;
两个动作:销毁给定的指针指向的对象;释放对应的内存。
4.未定义的行为:释放一块并非new分配的内存,或者将相同的指针释放多次。编译器无法区分出这两种情况。
5:动态对象的生存期直到被释放为止。
对于智能指针:shared_ptr管理的内存在最后一个shared_ptr销毁时会被自动释放。
内置指针类型管理的内存:动态对象直到被显示释放之前它都是存在的。以下都是此类:
返回指向动态内存的指针的函数给调用者增加了额外负担,调用者必须记得释放内存。调用此函数时,使用了指针而不delete,离开作用域时局部变量指针被销毁,而不会发生什么,动态内存在显示释放之前一直会存在;
在调用函数中必须记得释放内存,否则指向这块内存的指针被销毁则没有办法释放这块内存了。如果还有其他代码要使用这个指针,则返回一个指针,指向它分配的内存。