C++Primer第五版 第十三章习题答案(31~40)

来源:互联网 发布:白鲨的淘宝店 编辑:程序博客网 时间:2024/05/21 10:20

31:这几题都是举例使用动态内存管理类,多是代码,多写写

#include<iostream>  #include<string>#include<vector>#include<algorithm>using namespace std;class Hasptr1{friend void swap(Hasptr1&,Hasptr1&);friend bool operator<(const Hasptr1& s1,const Hasptr1& s2);friend void show(vector<Hasptr1>& vec);public://构造函数,初始化相关成员Hasptr1(const string& s = string()):ps(new string(s)),i(0),use(new size_t(1)){}//拷贝构造函数,将引用计数也拷贝过来,并且递增引用计数Hasptr1(const Hasptr1& p):ps(p.ps),i(p.i),use(p.use){++*use;}//拷贝赋值运算符Hasptr1& operator= (const Hasptr1& p1){++*p1.use;//首先递增右侧运算符对象的引用计数if (--*use == 0)//递减本对象的引用计数,若没有其他用户,则释放本对象的成员{delete ps;delete use;}ps = p1.ps;//进行拷贝use = p1.use;i = p1.i;return *this;}//析构函数~Hasptr1(){if (*use == 0)//引用计数变为0,说明已经没有对象再需要这块内存,进行释放内存操作{delete ps;delete use;}}private://定义为指针,是我们想将该string对象保存在动态内存中string *ps;size_t *use;//将计数器的引用保存int i;};inline void swap(Hasptr1& a,Hasptr1& b){using std::swap;swap(a.ps,b.ps);std::swap(a.i,b.i);cout<<"123";}bool operator< (const Hasptr1& s1,const Hasptr1& s2){cout<<"定义的 Operator< 被调用"<<endl;return *s1.ps < *s2.ps;}void show(vector<Hasptr1>& vec){vector<Hasptr1>::iterator it1 = vec.begin();for (it1; it1 != vec.end(); ++it1){cout<<*(it1->ps)<<endl;}}int main(int argc, char**argv)  {vector<Hasptr1> vec1;Hasptr1 a("l");Hasptr1 b("llll");Hasptr1 c("lll");vec1.push_back(a);vec1.push_back(b);vec1.push_back(c);vector<Hasptr1>::iterator it1 = vec1.begin();sort(vec1.begin(),vec1.end());show(vec1);return 0;}  


32:类指针的类版本,使用编译器自带的swap()函数即可完成目标操作,并不需要自定义一个swap以交换指针所指向的值,所以并不会提升效果


33:我们的目的是对传入的folder进行修改,传值的方式会使得我们修改的是其副本,const修饰符使得我们不能对其进行修改。所以都不行


34:

#ifndef MESSAGE_H//防止头文件重复包含#define MESSAGE_H#include <string>#include <set>using namespace std;class Message{friend class Folder;public:Message(const Message& m):contents(m.contents),folders(m.folders)//拷贝构造函数{add_to_Folders(m);//拷贝时,将新创建的message的指针添加到每个包含的folder中}Message& operator=(const Message& mm)//拷贝赋值运算符{remove_from_Folders();//删除自身contents = mm.contents;folders = mm.folders;add_to_Folders(mm);//将本message传入folder中return *this}Message(const string &str = ""):contents(str){}//构造函数void swap(Message& m1,Message& m2){using std::swap;//先将每个message从其folders中删除for(auto f : m1.folders){f->remMsg(this);//所有包含此message的folder进行删除操作}for(auto f : m2.folders){f->remMsg(this);//所有包含此message的folder进行删除操作}swap(m1.folders,m2.folders);swap(m1.contents,m2.contents);for (auto f : m1.folders){f->addMsg(this);//再进行添加操作}for (auto f : m2.folders){f->addMsg(this);}}~Message()//析构函数{remove_from_Folders();}void save(Folder&);void remove(Folder&);//对Folder类的操作函数private:string contents;//信息内容set<Folder*> folders;//包含本message的folder序列void add_to_Folders(const Message&);void remove_from_Folders();//从folders中删除本message};void Message::save(Folder& f){folders.insert(&f);//将给定folder加入到我们的folders中f.addMsg(this);//将本message添加到给定folder中}void Message::remove(Folder& f){folders.erase(&f);//将给定folder在我们的folders中删除f.remMsg(this);//将本message在给定folder中删除}void Message::add_to_Folders(const Message& m){for (auto f : m.folders){f->addMsg(this);}}void Message::remove_from_Folders(){for (auto f : folders){f->remMsg(this);//所有包含此message的folder进行删除操作}}#endif MESSAGE_H


35:若使用合成的拷贝控制成员,则folders不会更新,所包含信息错乱


36:

class Folder{public:Folder();~Folder();Folder& operator=(const Folder&);Folder(const Folder&);void addMsg(Message *m3)//上面需要使用this作为参数,所以这里需要用指针{messages.insert(m3);}void remMsg(Message *m4){messages.erase(m4);}private:set<Message*> messages;//保存Message的指针};


37:见34题代码


38:当涉及到动态分配内存时,拷贝并交换是一个完成该功能的精简的方式. ,但是在Message类中,并未涉及到动态分配内存,这种方法并不会产生任何益处,同时还会因为很多指针操作让程序变得更复杂难难以实现


39:

void StrVec::alloc_n_move(size_t new_cap){auto newdata = alloc.allocate(new_cap);auto dest = newdata;auto elem = elements;for (size_t i = 0; i != size(); ++i)alloc.construct(dest++, std::move(*elem++));free();elements = newdata;first_free = dest;cap = elements + new_cap;}void StrVec::reallocate(){auto newcapacity = size() ? 2 * size() : 1;alloc_n_move(newcapacity);}void StrVec::reserve(size_t new_cap){if (new_cap <= capacity()) return;alloc_n_move(new_cap);}void StrVec::resize(size_t count){resize(count, std::string());}void StrVec::resize(size_t count, const std::string& s){if (count > size()) {if (count > capacity()) reserve(count * 2);for (size_t i = size(); i != count; ++i)alloc.construct(first_free++, s);}else if (count < size()) {while (first_free != elements + count) alloc.destroy(--first_free);}}


40:主要为三个指针进行初始化,并将成员进行赋值

StrVec(initializer_list<string>lst){     auto newdata=alloc_n_copy(lst.begin(),lst.end());      elements=newdata.first;      first_free=cap=newdata.second;  }  



2 0
原创粉丝点击