练习12.1 都是4个
练习12.2
#ifndef MYSTRBLOB_H
#define MYSTRBLOB_H
#include
#include
#include
#include
#include
class StrBlob {
friend class StrBlobPtr;
public:
typedef std::vector::size_type size_type;
// constructors
StrBlob() : data(std::make_shared>()) { }
StrBlob(std::initializer_list il);
// size operations
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
// add and remove elements
void push_back(const std::string &t) { data->push_back(t); }
void pop_back();
// element access
std::string& front();
std::string& back();
std::string& front() const;
std::string& back() const;
private:
std::shared_ptr> data;
// throws msg if data[i] isn't valid
void check(size_type i, const std::string &msg) const;
};
StrBlob::StrBlob(std::initializer_list il) : data(std::make_shared>(il)){}
void StrBlob::pop_back() {
check(0,"pop_back on empty StrBlob");
data->pop_back();
}
void StrBlob::check(size_type i, const std::string& msg)const {
if (i >= data->size())
throw std::out_of_range(msg);
}
std::string& StrBlob::back() {
check(0,"back on empty StrBlob");
return data->back();
}
std::string& StrBlob::front() {
check(0, "front on empty StrBlob");
return data->front();
}
std::string& StrBlob::back() const{
check(0,"back on empty StrBlob");
return data->back();
}
std::string& StrBlob::front() const{
check(0, "front on empty StrBlob");
return data->front();
}
#endif
练习12.3 不需要 对象内容改变不需要对象是const类型。
练习12.4 i是size_type无符号型整数
练习12.5 优点:可以隐式转换,可以赋值构造 缺点:在不需要转换的地方可能自动转换。
练习12.6
void input(vector* p) {
int k;
while(cin>>k)
p->push_back(k);
}
void output(vector* p) {
for(auto k: *p)
cout << k << ' ';
}
int main(int argc, char const *argv[])
{
vector* p1 = new vector;
input(p1);
output(p1);
delete(p1);
return 0;
}
练习12.7
void input(shared_ptr> p) {
int k;
while(cin>>k)
p->push_back(k);
}
void output(shared_ptr> p) {
for(auto k: *p)
cout << k << ' ';
}
int main(int argc, char const *argv[])
{
shared_ptr> p1 = make_shared>();
input(p1);
output(p1);
return 0;
}
练习12.8 没有
练习12.9 line 2: r内存泄漏 line 4: r2指向q2指向的内存,原r2收回。
练习12.10 正确
练习12.11 p指向的内存被删除但还有可能使用p
练习12.12 a 合法 b 不合法 不能赋值内置指针给共享指针 c不合法,同b d合法
练习12.13 sp失效
练习12.15
void f(destination &d) {
connection c = connect(&d);
shared_ptr p(&c, [](connection*p) {disconnect(p);});
}
练习12.17 (a) 非法,将整数赋值智能指针 (b) 非法,将非动态内存赋值 (c)合法 (d) 同b (e)合法 (f)合法但可能使用无效p2
练习12.18 unique_ptr只能独享动态变量,因此改变所有权的时候需要release,而共享指针指向的对象由多个指针指向,不需要release。
练习12.19
#ifndef MYSTRBLOB_H
#define MYSTRBLOB_H
#include
#include
#include
#include
#include
using namespace std;
class StrBlobPtr;
class StrBlob {
friend class StrBlobPtr;
friend class ConstStrBlobPtr;
public:
typedef vector::size_type size_type;
// constructors
StrBlob() : data(make_shared>()) { }
StrBlob(initializer_list il);
// size operations
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
// add and remove elements
void push_back(const string &t) { data->push_back(t); }
void pop_back();
// element access
string& front();
string& back();
string& front() const;
string& back() const;
StrBlobPtr begin();
StrBlobPtr end();
ConstStrBlobPtr cbegin() const;
ConstStrBlobPtr cend() const;
private:
shared_ptr> data;
// throws msg if data[i] isn't valid
void check(size_type i, const string &msg) const;
};
StrBlob::StrBlob(initializer_list il) : data(make_shared>(il)){}
void StrBlob::pop_back() {
check(0,"pop_back on empty StrBlob");
data->pop_back();
}
void StrBlob::check(size_type i, const string& msg)const {
if (i >= data->size())
throw out_of_range(msg);
}
string& StrBlob::back() {
check(0,"back on empty StrBlob");
return data->back();
}
string& StrBlob::front() {
check(0, "front on empty StrBlob");
return data->front();
}
string& StrBlob::back() const{
check(0,"back on empty StrBlob");
return data->back();
}
string& StrBlob::front() const{
check(0, "front on empty StrBlob");
return data->front();
}
class StrBlobPtr
{
public:
StrBlobPtr():curr(0){}
StrBlobPtr(StrBlob& a, size_t sz = 0): wptr(a.data), curr(sz){}
string& deref() const;
StrBlobPtr& incr();
private:
weak_ptr> wptr;
size_t curr;
shared_ptr> check(size_t index, const string& msg) const;
};
inline StrBlobPtr StrBlob::begin() { return StrBlobPtr(*this);}
inline StrBlobPtr StrBlob::end() {
return StrBlobPtr(*this, data->size());
}
string& StrBlobPtr::deref() const {
auto p = check(curr, "out of range");
return (*p)[curr];
}
StrBlobPtr& StrBlobPtr::incr() {
check(curr, "increment past end of StrBlobPtr");
curr++;
return *this;
}
shared_ptr> StrBlobPtr::check(size_t index, const string& msg) const {
auto p = wptr.lock();
if(!p)
throw runtime_error("unbound StrBlobPtr");
else if (curr >= p->size())
throw runtime_error(msg);
else
return p;
}
练习12.20
int main(int argc, char const *argv[])
{
StrBlob sb;
string s;
while(cin>>s)
sb.push_back(s);
StrBlobPtr sbp = sb.begin();
int n = sb.size();
while(n--) {
cout << sbp.deref()<
练习12.21 前一个,更清晰。
练习12.22
class ConstStrBlobPtr
{
public:
ConstStrBlobPtr():curr(0){}
ConstStrBlobPtr(const StrBlob& a, size_t sz = 0): wptr(a.data), curr(sz){}
string& deref() const;
ConstStrBlobPtr& incr();
private:
weak_ptr> wptr;
size_t curr;
shared_ptr> check(size_t index, const string& msg) const;
};
inline ConstStrBlobPtr StrBlob::cbegin() const{ return ConstStrBlobPtr(*this);}
inline ConstStrBlobPtr StrBlob::cend() const{
return ConstStrBlobPtr(*this, data->size());
}
string& ConstStrBlobPtr::deref() const {
auto p = check(curr, "out of range");
return (*p)[curr];
}
练习12.23
char* concat(const char* a, const char* b) {
char* p = new char[strlen(a)+strlen(b)];
int i = 0;
for(; i < strlen(a); i++)
p[i] = a[i];
for(int j = 0; j <= strlen(b); j++)
p[i+j] = b[j];
return p;
}
int main(int argc, char const *argv[])
{
auto p = concat("hello ", "world");
for(int i = 0; i < strlen(p); i++)
cout << p[i];
cout << endl;
return 0;
}
string concat(const char* a, const char* b) {
string a1 = a, b1 = b;
return a1+b1;
}
int main(int argc, char const *argv[])
{
auto p = concat("hello ", "world");
cout << p <
练习12.24
char* input() {
char c;
char* p = new char[10];
int i = 0, size = 10;
while(cin>>c) {
p[i] = c;
i++;
if (i >= size) {
size *= 2;
char* tmp = new char[size];
for(int j = 0; j < i; j++)
tmp[j] = p[j];
delete [] p;
p = tmp;
}
}
p[i] = '\0';
return p;
}
int main(int argc, char const *argv[])
{
string p = input();
cout << p<
练习12.25 delete[] pa;
练习12.26
int main(int argc, char const *argv[])
{
allocator alloc;
int size = 10;
auto beg = alloc.allocate(size);
auto cur = beg;
string s;
while(cin >> s && cur - beg < size) {
alloc.construct(cur++,s);
}
while(cur != beg){
cout << *--cur << endl;
alloc.destroy(cur);
}
alloc.deallocate(beg, size);
}
练习12.27
class QueryResult;
class TextQuery{
friend class QueryResult;
vector* text;
unordered_map> lines;
public:
TextQuery(ifstream& input) {
text = new vector();
string s;
int line = 0;
while(getline(input,s)) {
text->push_back(s);
string tmp;
istringstream inw(s);
while(inw >> tmp)
lines[tmp].insert(line);
line++;
}
}
QueryResult query(string s);
};
class QueryResult
{
friend ostream& print(ostream& os, QueryResult q);
set l;
vector* text;
public:
QueryResult(TextQuery& t, string& s) {
l = t.lines[s];
text = t.text;
};
};
QueryResult TextQuery::query(string s) {
return QueryResult(*this, s);
}
ostream& print(ostream& os, QueryResult q){
if(q.l.size() == 0)
os << "word not found"<
练习12.28
int main(int argc, char const *argv[])
{
vector text;
ifstream infile(argv[1]);
string s;
unordered_map> lines;
int line = 0;
while(getline(infile, s)) {
text.push_back(s);
string tmp;
istringstream ssin(s);
while(ssin >> tmp)
lines[tmp].insert(line);
line++;
}
while(true) {
cout << "please input the word you want to query or input q to quit:";
if(!(cin >> s) || s == "q")
break;
auto res = lines[s];
if(res.size() == 0)
cout << "word "<< s<<" not found!"<
练习12.29
void runQueries(ifstream& infile) {
TextQuery tq(infile);
do{
cout << "enter the word to look for, or q to quit: ";
string s;
if (!(cin>>s) || s=="q")break;
print(cout, tq.query(s)) << endl;
}while(true);
}
练习12.30
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "MyStrBlob.h"
using namespace std;
class QueryResult;
class TextQuery{
shared_ptr> text;
unordered_map>> lines;
public:
TextQuery(ifstream& input) {
text = make_shared>();
string s;
int line = 0;
while(getline(input,s)) {
text->push_back(s);
string tmp;
istringstream inw(s);
while(inw >> tmp) {
auto& p = lines[tmp];
if(!p)
p.reset(new set);
p->insert(line);
}
line++;
}
}
QueryResult query(string& s);
};
class QueryResult
{
friend ostream& print(ostream& os, const QueryResult& q);
shared_ptr> l;
shared_ptr> text;
string word;
public:
QueryResult(string& s, shared_ptr> lines ,shared_ptr> t) {
l = lines;
word = s;
text = t;
};
};
QueryResult TextQuery::query(string& s) {
auto p = lines.find(s);
if(p == lines.end())
return QueryResult(s, make_shared>(), text);
else {
cout << p->second->size()<second, text);
}
}
ostream& print(ostream& os, const QueryResult& q){
if(q.l->size() == 0)
os << "word "<>s) || s=="q")break;
print(cout, tq.query(s)) << endl;
}while(true);
}
int main(int argc, char const *argv[])
{
vector text;
ifstream infile(argv[1]);
runQueries(infile);
return 0;
}
练习12.31 set好,自动去重排序。
练习12.32
class TextQuery{
StrBlob text;
unordered_map>> lines;
public:
TextQuery(ifstream& input) {
string s;
int line = 0;
while(getline(input,s)) {
text.push_back(s);
string tmp;
istringstream inw(s);
while(inw >> tmp) {
auto& p = lines[tmp];
if(!p)
p.reset(new set);
p->insert(line);
}
line++;
}
}
QueryResult query(string& s);
};
class QueryResult
{
friend ostream& print(ostream& os, const QueryResult& q);
shared_ptr> l;
StrBlob text;
string word;
public:
QueryResult(string& s, shared_ptr> lines , StrBlob t) {
l = lines;
word = s;
text = t;
};
};
ostream& print(ostream& os, const QueryResult& q){
if(q.l->size() == 0)
os << "word "<
练习12.33
class QueryResult
{
friend ostream& print(ostream& os, const QueryResult& q);
shared_ptr> l;
shared_ptr> text;
string word;
public:
QueryResult(string& s, shared_ptr> lines ,shared_ptr> t) {
l = lines;
word = s;
text = t;
};
set::iterator begin(){return l->begin();};
set::iterator end(){return l->end();}
shared_ptr> get_file(){return text;};
};