智能指针(二)--练习

智能指针--练习

#include<iostream>
#include<string>
#include<vector>
#include<memory>
#include<fstream>
#include<initializer_list>
using namespace std;
class StrBlobPtr; //仅仅是声明,在该类为完全定义完整之前,只能使用其类型,而不能调用其成员和函数
class StrBlob {
    friend class StrBlobPtr;
public:
    typedef vector<string>::size_type size_type;
    StrBlob();
    StrBlob(initializer_list<string>il);
    StrBlob(vector<string>stp);
    StrBlob(shared_ptr<vector<string>>tp);
    size_type size() const { return data->size();};
    bool empty()const { return data->empty(); }
    //add & delete
    void push_back(const string& t) { data->push_back(t); }
    void pop_back();
    //visit data
    string& front();
    string& front()const;
    string& back();
    string& back()const;
    //begin和end,返回指向自身的StrBlobPtr,此时不能被定义,知道strBlobPtr被定义完了之后才行,否则C2027
    StrBlobPtr begin();
    StrBlobPtr end();
    StrBlobPtr begin()const;// const版本使得StrBlobPtr可以指向const的StrBlob
    StrBlobPtr end()const;
private:
    shared_ptr<vector<string>>data;
    //check the index of data
    void check(size_type i, const string& msg)const;
};
StrBlob::StrBlob():data(make_shared<vector<string>>()) {}
StrBlob::StrBlob(initializer_list<string>il):
    data(make_shared<vector<string>>(il)) {}
StrBlob::StrBlob(vector<string> stp):
    data(make_shared<vector<string>>(stp)){}
StrBlob::StrBlob(shared_ptr<vector<string>> tp):data(tp){}
void StrBlob::check(size_type i, const string& msg)const
{
    if (i >= data->size())
        throw out_of_range(msg);
}
string& StrBlob::front()
{
    check(0, "front on the empty Strblob");
    return data->front();
}
string& StrBlob::front()const
{
    check(0, "front on the empty Strblob");
    return data->front();
}
string& StrBlob::back()
{
    check(0, "back on the empty Strblob");
    return data->back();
}
string& StrBlob::back()const
{
    check(0, "back on the empty Strblob");
    return data->back();
}
void StrBlob::pop_back()
{
    check(0, "pop_back on the empty Strblob");
    return data->pop_back();
}
class StrBlobPtr {
public:
    StrBlobPtr() :curr(0) {}
    StrBlobPtr(StrBlob &a,size_t sz=0):curr(sz),wptr(a.data) {}
    StrBlobPtr(const StrBlob& a, size_t sz = 0) :curr(sz), wptr(a.data) {}
    string& deref()const;//解引用获取元素
    StrBlobPtr& incr();  //前缀递增
    StrBlobPtr& decr();  //递减
    bool equal(const StrBlobPtr& , const StrBlobPtr& );
private:
    //如果检查成功,就check返回一个指向vector的shared_ptr
    shared_ptr<vector<string>> check(size_t, const string&)const;
    //保存一个weak_ptr,意味着底层vector可能被销毁
    weak_ptr<vector<string>>wptr;
    size_t curr;//在数组中当前的位置
};
shared_ptr<vector<string>> StrBlobPtr::check(size_t i , const string& msg)const {
    auto ret = wptr.lock(); //查看是否vector还存在
    if (!ret)
        throw runtime_error("unbound StrBlobPtr");
    if (i >= ret->size())
        throw out_of_range("msg");
    return ret;     //否则返回指向vector的shared_ptr
}
string& StrBlobPtr::deref()const {
    //调用check,检查vector是否安全以及curr是否在范围内
    auto p = check(curr, "dereference past end");
    return (*p)[curr];      //解引用p获得vector,然后使用下标操作提取并返回curr位置上的元素
}
StrBlobPtr& StrBlobPtr::incr(){
    //如果curr已经指向容器的尾后位置,则不能引用它
    check(curr, "increment past end of StrBlobPtr");
    ++curr;//推进当前位置
    return *this;
}
StrBlobPtr& StrBlobPtr::decr()
{
    --curr;
    check(-1, "decrement past begin of StrBlobPtr");
    return *this;
}
bool StrBlobPtr::equal(const StrBlobPtr& beg, const StrBlobPtr& end)
{

    auto b = beg.wptr.lock(), e = end.wptr.lock();
    if (beg.curr == end.curr)
        return true;
    else
        return false;
}
StrBlobPtr StrBlob::begin()
{
    return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()
{
    auto ret = StrBlobPtr(*this, data->size());
    return ret;
}
StrBlobPtr StrBlob::begin()const
{
    return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()const
{
    auto ret = StrBlobPtr(*this, data->size());
    return ret;
}
void readline(string ifile, vector<string> &str) {//将文件内容读入到一个string的vector容器中去
    vector<string>::iterator it;
    string tmp;
    str.clear();
    ifstream openfile(ifile + ".txt", ifstream::in);  //以读模式打开一个文件
    while (getline(openfile, tmp)) {        //没有到达文件的尾部
                //读入一行
        str.push_back(tmp);         //每一行作为独立元素存入vector中
    }
    if (str.empty()) {              //没有数据,直接返回
        cout << "No data?!" << endl;
        return;
    }
    /*
    it = str.begin();
    for (; it != str.end(); it++)   //输出文件内容(存入vector中的)
        cout << (*it) << endl;
    */
    openfile.close();               //关闭文件流
}
auto init_vec() {
    auto p = new vector<int>;
    return p;
}
auto init_vec_shared() {
    auto p = make_shared<vector<int>>();
    return p;
}
auto read_vec(istream&in ,vector<int>* p) {
    int tmp = 0;
    while (in>>tmp) {
        p->push_back(tmp);
    }
    return p;
}
auto read_vec_shared(istream& in, shared_ptr<vector<int>>p) {
    int tmp = 0;
    while (in >> tmp) {
        p->push_back(tmp);
    }
    return p;
}
void dis_vec(vector<int>* p) {
    for (auto i = p->begin(); i != p->end(); i++) {
        cout << *i << endl;
    }
    delete p;
}
void dis_vec_shared(shared_ptr<vector<int>>p) {
    for (auto i = p->begin(); i != p->end(); i++) {
        cout << *i << endl;
    }
}
void process(shared_ptr<int>ptr) {
    cout << *ptr << endl;
}
int main(void) {

    //dis_vec(read_vec(cin, init_vec()));  从键盘读入,然后输出
    //dis_vec_shared(read_vec_shared(cin, init_vec_shared())); 从键盘读入,然后输出

    //从文件读入,然后输出
    vector<string>st;
    readline("test", st);
    StrBlob a(st);
    StrBlobPtr b(a.begin());
    while (!b.equal(b,a.end())) {
        cout << b.deref() << endl;
        b.incr();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/FlyerBird/p/12336861.html

时间: 2024-11-09 04:00:17

智能指针(二)--练习的相关文章

解释清楚智能指针二【用自己的话,解释清楚】

写在前面 用自己的话分析清楚~ 智能指针是如何使用的? 强指针是如何实现? 弱指针如何转化为强指针? 智能指针的使用 智能指针的使用必须满足如下条件: 这个类需要继承自RefBase 为什么需要虚析构函数? 虚析构函数是为了解决这样的一个问题:基类的指针指向派生类对象,并用基类的指针删除派生类对象.虚函数的出现是为了解决多态问题. 满足上述条件的类就可以定义智能指针了,普通的指针使用如下方式: MyClass *p_obj; 智能指针是这样定义: Sp<MyClass> p_obj; 强指针的

智能指针(二):shared_ptr实现原理

前面讲到auto_ptr有个很大的缺陷就是所有权的转移,就是一个对象的内存块只能被一个智能指针对象所拥有.但我们有些时候希望共用那个内存块.于是C++ 11标准中有了shared_ptr这样的智能指针,顾名思义,有个shared表明共享嘛.所以shared_ptr类型的智能指针可以做为STL容器的元素 下面我们来瞧瞧shared_ptr具体是咋实现的.相较auto_ptr有下面几个不同的地方: 1.引进了一个计数器shared_count,用来表示当前有多少个智能指针对象共享指针指向的内存块 2

深入学习c++--智能指针(二) weak_ptr(打破shared_ptr循环引用)

1. 几种智能指针 1. auto_ptr: c++11中推荐不使用他(放弃) 2. shared_ptr: 每添加一次引用 就+1,减少一次引用,就-1:做到指针进行共享 3. unique_ptr: 一个指针同时只能有一个使用者使用 4. weaked_ptr: 与shared_ptr搭配使用 1.1 weak_ptr 参考:https://zh.cppreference.com/w/cpp/memory/weak_ptr std::weak_ptr 是一种智能指针,它对被 std::sha

Android架构分析之Android智能指针(二)

作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android版本:4.4.2 在上一篇文章中,我们分析了Android智能指针中的强指针sp,本文我们来分析弱指针wp.为什么需要弱指针wp呢?我们来考虑下面一种场景:有两个类CParent和CChild,CParent类中有一个智能指针指向CChild对象,CChild类中有一个智能指针指向CParent对象 class CParent :public LightRefBase<CParent> { --

C++primer第十二章读书笔记---动态内存与智能指针

    目前为止我们使用过的静态内存,栈内存和内存池,静态内存用来保存局部static对象.类static成员,以及定义在任何函数之外的成员.栈内存用来保存定义在函数内部的非static成员,分配在静态 内存或栈内存中的对象由编译器自动创建或销毁,对于栈对象仅在其定义的程序块运行时才有效,static对象在程序运行之前分配,程序结束时销毁.除了静态内存和栈内存外,每个程序还拥有一个内存池(堆)在堆上分配动态对象,当动态对象不再使用时,我们必须显示的销毁它.     (一).动态内存与智能指针  

C++ 智能指针详解 二

智能指针(smart pointer)是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动态分配的对象,防止内存泄露.它的一种通用实现技术是使用引用计数(reference count).智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针.每次创建类的新对象时,初始化指针并将引用计数置为1:当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数:对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果

ReactNative 4Android源码分析二: 《JNI智能指针之实现篇》

文/Tamic http://blog.csdn.net/sk719887916/article/details/53462268 回顾 上一篇介绍了<ReactNative4Android源码分析2: JNI智能指针之介绍篇>JNI智能指针与wrapper class的作用,下面将对它们的具体实现进行分析,并解答上篇提出的几个问题 前文回顾了java object在JNI中的引用对象jobject的3种类型.智能指针自然也有相应的如下类型: global_ref 全局指针与jobject全局

C++ template —— 智能指针(十二)

在管理动态分配的内存时,一个最棘手的问题就是决定何时释放这些内存,而智能指针就是用来简化内存管理的编程方式.智能指针一般有独占和共享两种所有权模型.------------------------------------------------------------------------------------------------------------20.1 holder和trule本节将介绍两种智能指针类型:holder类型独占一个对象:而trule可以使对象的拥有者从一个hold

第十二章 动态内存与智能指针

动态内存与智能指针 [智能指针]头文件#include<memory>shared_ptr: 允许多个指针指向同一个对象unique_ptr: "独占"所指向的对象weak_ptr:伴随类,它是一种弱引用,指向shared_ptr所管理的对象. 原文地址:https://www.cnblogs.com/sunbines/p/8552298.html