C++ Primer 学习笔记 第十二章 动态内存与智能指针

402 创建智能指针

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
using namespace std;

int main() {
    shared_ptr<string> p1;
    shared_ptr<list<int>> p2;
    if (p1->empty())
        *p1 = "hi";

    shared_ptr<int> p3 = make_shared<int>(42);
    shared_ptr<string> p4 = make_shared<string>(10, '9');
    shared_ptr<int> p5 = make_shared<int>();
    auto p6 = make_shared<vector<string>>();

    auto p = make_shared<int>(42);
    auto q(p);

    auto r = make_shared<int>(42);
    r = q;
    
    return 0;
}

402 智能指针例子

int main() {
    initializer_list<string> lst = {"a", "b", "c"};
    shared_ptr<initializer_list<string>> li = make_shared<initializer_list<string>>(lst);
    cout << *li->begin() << endl;


    int num =1;
    shared_ptr<int> pi = make_shared<int>(num);
    cout << *pi << endl;
    
//    StrBlob demo(lst);
//    cout << demo.front() << endl;

    return 0;
}

405 复习一下在类外定义构造函数

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
using namespace std;


class Sales_data{
public:
Sales_data();
Sales_data(const string &s);

string show_data(){
return this->data;
}

private:
string data;
};

// 没有传入string时候,初始化默认的data
Sales_data::Sales_data():data(string("sdds")){}
// 传入string时候初始化data
Sales_data::Sales_data(const string &s):data(s) {};


int main() {
Sales_data demo;
cout << demo.show_data() << endl;
return 0;
}

StrBlob类

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
using namespace std;


class StrBlob{
public:
    typedef std::vector<std::string>::size_type size_type;
    StrBlob();
    StrBlob(std::initializer_list<std::string> il);

    size_type size() const {return data->size();};
    bool empty() const {return data->empty();};

    void push_back(const std::string &t){data->push_back(t);};
    void pop_back();

    std::string& front();
    std::string& back();

private:
    std::shared_ptr<std::vector<std::string>> data;
    void check(size_type i, const std::string &msg) const;
};


StrBlob::StrBlob() :data(make_shared<vector<string>>()){}
StrBlob::StrBlob(initializer_list<string> il):data(make_shared<vector<string>>(il)){}
void StrBlob::check(size_type i, const std::string &msg) const {
    if (i>=data->size())
        throw out_of_range(msg);
}

string& StrBlob::front() {
    check(0, "front on empty StrBlob");
    return data->front();
}
string& StrBlob::back() {
    check(0, "back on empty StrBlob");
    return data->back();
}
void StrBlob::pop_back() {
    check(0, "pop_back on empty StrBlob");
    data->pop_back();
}


int main() {
    initializer_list<string> s = {"1", "2", "3"};
    StrBlob demo(s);
    cout << demo.front() << endl; //1
    cout << demo.back() << endl; //3
    demo.pop_back();
    cout << demo.size() << endl; // 2
    cout << demo.back() << endl; // 2

    return 0;
}

407 动态内存分配和初始化对象

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
using namespace std;



int main(){
    int *pi = new int;
    string *ps = new string;

    int *pi2 = new int(1024);
    string *ps2 = new string(10, '9');
    vector<int> *pv2 = new vector<int>{0, 1, 2, 3};


    string *ps3 = new string;
    string *ps4 = new string();
    int *pi3 = new int;
    int *pi4 = new int();

    int num1 = 2;
    int *pi5 = new auto(num1);

    const int *pci = new const int(1024);
    const string *pcs = new const string;


    return 0;
}

delete

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
using namespace std;



int main(){
    int *p1 = new int;
    int *p2 = new (nothrow) int;

    int num = 3;
    int *p3 = &num;
    // error
    // delete p3;

    int i, *pi1 = &i, *pi2 = nullptr;
    double *pd = new double(33), *pd2 = pd;
    // error
    // delete i;
    // error
//    delete pi1;
    delete pd;
    // error
//    delete pd2;
    delete pi2;

    return 0;
}

动态内存例子

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
using namespace std;



int main(){
    int *p1 = new int;
    int *p2 = new (nothrow) int;

    int num = 3;
    int *p3 = &num;
    // error
    // delete p3;

    int i, *pi1 = &i, *pi2 = nullptr;
    double *pd = new double(33), *pd2 = pd;
    // error
    // delete i;
    // error
//    delete pi1;
    delete pd;
    // error
//    delete pd2;
    delete pi2;

    const int *pci = new const int(1024);
    delete pci;

    return 0;
}

411 动态内存的坑

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
using namespace std;



int main(){
    int *p(new int(42));
    auto q = p;
    delete p;
    p = nullptr;
    // 释放了p以后,q已经为无效了,但是很难被察觉
    return 0;
    
}

12.6

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
using namespace std;


vector<int>* create(){
    return new vector<int>;
}


int main(){

    vector<int> *pv = create();

    vector<int> vec = {1, 2 ,3};
    for (auto val:vec){
        pv->push_back(val);
    }

    for (vector<int>::iterator iter=pv->begin(); iter!=pv->end(); ++iter){
        cout << *iter << " ";
    }
    delete pv;

    return 0;
}

12.7

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
using namespace std;


shared_ptr<vector<int>> create(){
    return make_shared<vector<int>>();
}


int main(){

    shared_ptr<vector<int>> pv = create();

    vector<int> vec = {1, 2 ,3};
    for (auto val:vec){
        pv->push_back(val);
    }

    for (vector<int>::iterator iter=pv->begin(); iter!=pv->end(); ++iter){
        cout << *iter << " ";
    }

    return 0;

}

412 智能指针和动态内存结合使用

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
using namespace std;

shared_ptr<int> clone(int p){

    return shared_ptr<int>(new int(p));
}


int main(){

    shared_ptr<double> p1;
    shared_ptr<int> p2(new int(42));

    // error
//    shared_ptr<int> p1 = new int(1024);
    shared_ptr<int> p3(new int(1024));
    return 0;

}

413 不要混合使用智能指针和普通指针

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
using namespace std;

void process(shared_ptr<int> ptr){

}

int main(){

//    shared_ptr<int> p(new int(42));
//    process(p);
//    int i = *p;

    // x is a normal pointer
    int *x(new int(1024));
    cout << *x << endl; // 1024
//    process(x);
    process(shared_ptr<int>(x));
    // x was released after process
    int j = *x;
    cout << j << endl; // null

    return 0;

}

判断智能指针是否共享对象

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
using namespace std;


int main(){
    shared_ptr<int> p(new int(42));
    int *q = p.get();

    {
        shared_ptr<int>(q);
    }
    cout << *p << endl;

//    p = new int(1024);
    p.reset(new int(1024));
    shared_ptr<int> p2 = p;

    if (!p.unique()){
        cout << "p not unique" << endl;
    }
    
    return 0;

}

12.14 重写share_ptr综合例子,连接程序

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
#include <string>
using namespace std;


struct destination{
    string des;
    destination(string des_): des(des_){}
};

struct connection{
    string conn;
    connection(string conn_): conn(conn_){}
};

connection connect(destination *des_){
    connection conn(des_->des);
    cout << "connect to " << des_->des << endl;
    return conn;
}

void disconnect(connection *conn){
    cout << "disconnect " << conn->conn << endl;

}

void end_connection(connection *p){
    // 固定格式
    disconnect(p);
}

void f(destination *des){
    connection conn = connect(des);
    
    // 固定格式
    shared_ptr<connection> p(&conn, end_connection);
    cout << "connecting " << des->des << " now" <<endl;

}


int main(){
    destination des("aa");
    f(&des);
    return 0;

}

12.15

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
#include <string>
using namespace std;


struct destination{
    string des;
    destination(string des_): des(des_){}
};

struct connection{
    string conn;
    connection(string conn_): conn(conn_){}
};

connection connect(destination *des_){
    connection conn(des_->des);
    cout << "connect to " << des_->des << endl;
    return conn;
}

void disconnect(connection *conn){
    cout << "disconnect " << conn->conn << endl;

}


void f(destination *des){
    connection conn = connect(des);
    // 固定格式
    shared_ptr<connection> p(&conn, [](connection *p){ disconnect(p);});
    cout << "connecting " << des->des << " now" <<endl;

}


int main(){
    destination des("aa");
    f(&des);
    return 0;

}

417 unique_ptr

#include<iostream>
#include<memory>
#include<string>

using namespace std;


int main() {
    unique_ptr<double> p1;
    unique_ptr<int> p2(new int(42));


    unique_ptr<string> p3(new string("aaabbbccc"));
    // error not support copying
//    unique_ptr<string> p4(p3);
    unique_ptr<string>p5;
    // error
//    p5 = p4;
    return 0;
}

unique_pt的控制权迁移

#include<iostream>
#include<memory>
#include<string>

using namespace std;


int main() {

    unique_ptr<string> p1(new string("ssss"));
    unique_ptr<string> p2(p1.release());
    unique_ptr<string> p3(new string("aaaa"));
    p2.reset(p3.release());

    cout << *p2 << endl;
    
    auto p = p2.release();
    delete p;
    return 0;
}

419 使用unique_ptr写连接程序

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
#include <string>
using namespace std;


struct destination{
    string des;
    destination(string des_): des(des_){}
};

struct connection{
    string conn;
    connection(string conn_): conn(conn_){}
};

connection connect(destination *des_){
    connection conn(des_->des);
    cout << "connect to " << des_->des << endl;
    return conn;
}

void disconnect(connection *conn){
    cout << "disconnect " << conn->conn << endl;

}

void end_connection(connection *p){
    // 固定格式
    disconnect(p);
}

void f(destination *des){
    connection conn = connect(des);

    // 固定格式
    unique_ptr<connection, decltype(end_connection)*> p(&conn, end_connection);
    cout << "connecting " << des->des << " now" <<endl;

}


int main(){
    destination des("aa");
    f(&des);

    return 0;

}

420 weak_ptr 弱共享

#include <iostream>
#include <memory>
#include <malloc.h>
#include <vector>
#include <string>
using namespace std;


int main(){
    auto p = make_shared<int>(42);
    shared_ptr<int> p2(p);
    weak_ptr<int> wp(p);
    cout << p.use_count() << endl;

    if (shared_ptr<int> np = wp.lock()){
        cout << *np << endl;
    }
    return 0;
}

12.19 - 12.20

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
using namespace std;


class StrBlob{
public:
    friend class StrBlobPtr;
    StrBlobPtr begin();
    StrBlobPtr end();

    typedef std::vector<std::string>::size_type size_type;
    StrBlob();
    StrBlob(std::initializer_list<std::string> il);

    size_type size() const {return data->size();};
    bool empty() const {return data->empty();};

    void push_back(const std::string &t){data->push_back(t);};
    void pop_back();

    std::string& front();
    std::string& back();
    std::shared_ptr<std::vector<std::string>> data;

private:
    void check(size_type i, const std::string &msg) const;
};


StrBlob::StrBlob() :data(make_shared<vector<string>>()){}
StrBlob::StrBlob(initializer_list<string> il):data(make_shared<vector<string>>(il)){}
void StrBlob::check(size_type i, const std::string &msg) const {
    if (i>=data->size())
        throw out_of_range(msg);
}

string& StrBlob::front() {
    check(0, "front on empty StrBlob");
    return data->front();
}
string& StrBlob::back() {
    check(0, "back on empty StrBlob");
    return data->back();
}
void StrBlob::pop_back() {
    check(0, "pop_back on empty StrBlob");
    data->pop_back();
}

class StrBlobPtr{
public:
    StrBlobPtr():curr(0){}
    StrBlobPtr(StrBlob &a, size_t sz=0):wptr(a.data), curr(sz){}
    string& deref() const;
    StrBlobPtr& incr();

private:
    shared_ptr<vector<string>> check(size_t, const string&) const;
    weak_ptr<vector<string>> wptr;
    size_t curr;
};

//shared_ptr<vector<string>>;
shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string &msg) const {
    auto ret = wptr.lock();
    if (!ret){
        throw runtime_error("unbound StrBlobPtr");
    }
    if (i>=ret->size())
        throw out_of_range(msg);
    return ret;
}

string& StrBlobPtr::deref() const {
    auto p = check(curr, "dereference past end");
    return (*p)[curr];
}

StrBlobPtr& StrBlobPtr::incr() {
    check(curr, "increment past end of StrBlobPtr");
    ++curr;
    return *this;
}

StrBlobPtr StrBlob::begin(){
    return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end(){
    return StrBlobPtr(*this, data->size());
}


int main() {
    StrBlob stb;
    StrBlobPtr stbr(stb);
    ifstream in("items.txt");
    string text;
    while (getline(in ,text)){
        stb.push_back(text);
        cout << text << endl;
    }
    cout << endl;

    auto begin = stb.begin();
    auto end = stb.end();


    while(true){

        try{
            cout <<stbr.deref() << endl;
            stbr.incr();
        } catch (...) {
            cout << "end of data" << endl;
            break;
        }

    }

    return 0;
}

423 动态数组的创建

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
using namespace std;


int main() {
    int *pia = new int[30];
    typedef int arrT[42];
    int *p = new arrT ;

    // init
    int *pia2 = new int[10]();  //  0 0 0 0 0 0 0 0 0 0

    for (size_t i=0; i!=10; ++i){
        cout << *(pia2+i) << " ";
    }
    cout << endl;

    int *pia3 = new int[10]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    string *psa3 = new string[10]{"a", "an", "the", string(3, 'x')}; //a an the xxx
    for (size_t i=0; i!=10; ++i){
        cout << *(psa3+i) << " ";
    }
    cout << endl;

    return 0;
}

425 释放动态数组

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
using namespace std;


int main() {
    int *p = new int[10];
    delete [] p;

    int *p2 = new int[10]();
    delete [] p2;
    
    return 0;
}

426 智能指针与动态数组

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
using namespace std;


int main() {
    unique_ptr<int[]> up(new int[10]);
    for (int i=0; i!=10; ++i){
        up[i] = i;
    }
    for (size_t i=0;i!=10;++i){
        cout << up[i] << " ";
    }
    cout << endl;
    up.release();

    shared_ptr<int> sp(new int [10], [](int *p){delete [] p;});
    sp.reset(new int[20]);

    for (size_t i=0; i!=10; ++i){
        *(sp.get() +i) = i;
    }
    for (size_t i=0; i!=10; ++i){
        cout << *(sp.get() +i) << " ";
    }
    cout << endl;
    return 0;
}

12.23

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
using namespace std;


int main() {
    const char a[] = "aaa";
    const char b[] = "bbb";
    char *ans = new char[strlen(a) + strlen(b)];
    strcpy(ans, a);
    strcat(ans, b);

    for (size_t i=0; i!=strlen(ans) + 1; ++i){
        cout << ans[i] << " ";
    }
    delete[] ans;
    return 0;
}

12.24

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
using namespace std;


int main() {
    const string a = "aaa";
    const string b = "bbb";
    string *ans = new string(a + b);
    for (auto item:*ans){
        cout << item << " ";
    }
    delete[] ans;

    return 0;
}

12.24

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
using namespace std;


int main() {
    char *ch = new char[3];
    string s;
    cin >> s;
    strcpy(ch, s.c_str());

    for (size_t i=0; i!=3; ++i){
        cout << ch[i] << " ";
    }
    cout << endl;
    return 0;

}

427

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
using namespace std;


int main() {
    size_t n = 5;
    string *const p = new string[n];
    string s;
    string *q = p;
    while (cin>>s && q != p + n){
        *q++ = s;
    }
    const size_t size = q - p;
    cout << size << endl;

    for (size_t i =0; i!=6; ++i){
        cout << p[i] << " ";
    }
    delete[] p;

    return 0;

}

427 使用allocate类动态分配内存,对象构造

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
using namespace std;


int main() {
    // allocating memory
    size_t n = 6;
    allocator<string> alloc;
    auto const p = alloc.allocate(n);

    auto q = p;
//    alloc.construct(q++);
//    alloc.construct(q++, 5, 'c');
    alloc.construct(q++, "hi");

    cout << *p << endl;
    while (q!=p){
        alloc.destroy(--q);
    }

    alloc.deallocate(p, n);
   return 0;

}

429

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
using namespace std;


int main() {
    vector<string> vi = {"a", "b", "c"};
    allocator<vector<string>> alloc;

    auto p = alloc.allocate(vi.size()*2);
    auto q = uninitialized_copy(vi.begin(), vi.end(), p);

    uninitialized_fill_n(q, vi.size(), 42);
    return 0;

}

12.26

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
using namespace std;


int main() {
    allocator<string> alloc;
    auto p = alloc.allocate(3);
    string s;
    auto q=p, r=p;

    while(cin>>s&&q!=p+3){
        alloc.construct(q++,s);
    }
    for (size_t i=0;i!=3; ++i){
        cout << *(r++) << " ";
    }
    cout << endl;
    while (q!=p){
        alloc.destroy(--q);
    }
    alloc.deallocate(p, 3);
    
    return 0;

}

430 文本查询程序的设计

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <set>
#include <iterator>
#include <memory>
#include <fstream>
#include <map>
#include <sstream>
using namespace std;
using line_no = vector<string>::size_type;



class QueryResult{
    friend ostream& print(ostream&, const QueryResult&);

public:
    QueryResult(string s,
                shared_ptr<set<line_no>> p,
                shared_ptr<vector<string>> f): sought(s), lines(p), file(f){}
private:
    string sought;
    shared_ptr<set<line_no>> lines;
    shared_ptr<vector<string>> file;
};


class TextQuery{
public:
    TextQuery(ifstream &);
    QueryResult query(const string&) const;

private:
    shared_ptr<vector<string>> file;
    map<string, shared_ptr<set<line_no>>> wm;
};
TextQuery::TextQuery(ifstream &is): file(new vector<string>) {
    string text;
    while (getline(is, text)){
        file->push_back(text);
        int n = file->size() - 1;
        istringstream line(text);
        string word;
        while (line>>word){
            auto &lines = wm[word];
            if (!lines)
                lines.reset(new set<line_no>);
            lines->insert(n);
        }
    }
}
QueryResult TextQuery::query(const string &sought) const {
    static shared_ptr<set<line_no>> nodata(new set<line_no>);
    auto loc = wm.find(sought);
    if (loc==wm.end()){
        return QueryResult(sought, nodata, file);
    } else{
        return QueryResult(sought, loc->second, file);
    }
}

string make_plural(size_t num, const string& input, const string& suffix){
    return (num > 1)? input+suffix:input;
}

ostream &print(ostream & os, const QueryResult &qr){
    os << qr.sought << " occurs " << qr.lines->size() << " " << make_plural(qr.lines->size(), "time", "s") << endl;
    for (auto  num:*qr.lines){
        os << "\t(line " << num+1 << ") " << *(qr.file->begin()+num) << endl;
    }
    return os;
}


void runQueries(ifstream &infile){
    TextQuery tq(infile);
    while (true){
        cout << "enter word to look for, or q to quit: ";
        string s;
        if (!(cin>>s)||s=="q") break;
        print(cout, tq.query(s)) << endl;
    }
}


int main() {
    ifstream in("input.txt");
    runQueries(in);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值