/*-----------StrBlob.h------------*/
#ifndef _STRBLOB_DATA_
#define _STRBLOB_DATA_
#include<iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
class StrBlobPtr;
class StrBlob;
class StrBlob
{
public:
typedef string::size_type size_type;
friend class StrBlobPtr;
StrBlob() :data(make_shared<vector<string>>()) {}; //initializer_list只是保证可以传动态的形参,可以用vector来装
StrBlob(vector<string> pri):data(make_shared<vector<string>>(pri)) {};
StrBlob(initializer_list<string> il) :data(make_shared<vector<string>>(il)) {};
size_type size() const { return data->size(); } //data是个指针,所以得用->
bool empty() const { return data->empty(); }
void push_back(const string &t) { data->push_back(t); }
void pop_back() { data->pop_back(); };
//元素访问,check先检查是否是空值
string &front() { check(0, "front on empty StrBlob"); return data->front(); }
string &back() { check(0, "back on empty StrBlob"); return data->back(); }
//无法仅按返回类型进行重载函数,因此加const就知道是const版得重载函数
string front()const;
string back()const;
StrBlobPtr begin();
StrBlobPtr end();
~StrBlob() {};
private:
shared_ptr<vector<string>> data; //创建一个智能指针,指向vector<string>;允许多个指针指向同一个对象
//如果data[i]不合法,将抛出一个异常
void check(size_type i, const string msg) const;
};
void StrBlob::check(size_type i, const string msg) const
{
if (i >= data->size())
throw out_of_range(msg);
}
string StrBlob::front()const
{ check(0, "front on empty StrBlob");
return data->front();
};
string StrBlob::back()const
{ check(0, "back on empty StrBlob");
return data->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 i, string msg) const;
weak_ptr <vector<string>> wptr;
size_t curr;
};
shared_ptr <vector<string>> StrBlobPtr::check(size_t i, 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()
{
auto p = check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
StrBlobPtr StrBlob::begin() { return StrBlobPtr(*this); };
StrBlobPtr StrBlob::end() { auto ret = StrBlobPtr(*this, data->size()); return ret; };
#endif // !_STRBLOB_DATA_
/*------------main.cpp-------------*/
#include<iostream>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <memory>
#include "StrBlob.h"
using namespace std;
vector<int> *exchange(const vector<int> put);
shared_ptr<vector<int>> my_exchange(const vector<int> put);
void _connect_s(const string &p, const string &p1, string *o);
bool b();
//void end_connect(connection *y);
void deleter(int *ptr);
void main()
{
StrBlob b1;
int input;
vector<int> get;
//std::cout << get->size()<<endl;
//while (cin >> input)
//{
// get.push_back(input);
//get.push_back(input);
//}
vector<int> *_change=exchange(get);//现在_change指向了new的那一片内存;当用完_change时,需要delete _change;
//否则那片内存还在,会导致内存泄漏
for (auto c : *_change)
std::cout << c << endl;
//delete _change;
auto g_change=my_exchange(get);
vector<decltype(g_change)> f;
for (auto c1 : *g_change) //记住g_change是个智能指针,它还是指针,所以得解引用
{
std::cout << c1 << endl; //其实c是它的引用,就是它本身,c1是局部变量,也是g_change的引用,
//当用完之后自动会被消除,从而那片内存也会被消除,但是书上说好像是拷贝才可以
//引用不行,引用就是它本身,并没有指向那片内存,它不是个对象
//c1用完自动被释放,从而那片内存也会被释放
}
f.push_back(g_change);
f.erase(f.begin()); //为了删除g_change所指的那片内存,但我感觉前面用c1已经删除了
//cout << b1.size() << endl;
if (b())
std::cout << "yes" << endl;
shared_ptr<int> p(new int(10), deleter);
shared_ptr<int> p1;
p1 = p; //当加了这个之后,就不会调用deleter,那我自己写个delete函数干嘛呢?
p= make_shared<int>(15); //当之前对10的那个内存的引用计数为0时,那么就删除10的那个内存,此时调用deleter这个函数
std::cout << *p;
//unique_ptr <int> ijj(new int(5));
//unique_ptr <int> jii(ijj); //unique_ptr不允许直接拷贝和赋值
ifstream file2_open("C:\\Users\\信计捡球员\\Desktop\\测试\\测试\\file_name2.txt", ifstream::in);
vector<string> _phones;
string _data_line;
//好好理解下面这段代码
istringstream _iss;
while (getline(file2_open, _data_line))
{
string p_name;
_iss.str(_data_line);
while (_iss >> p_name)
_phones.push_back(p_name);
}
cout << "----------------------" << endl;
StrBlob jpp(_phones);
StrBlobPtr kpp(jpp);
int n = jpp.size();
while (n--)
{
cout << kpp.deref() << endl;
kpp.incr();
}
int *kop = new int[10];
shared_ptr <int> sp(new int[10], [](int *p) {delete[]p; }); //自制lambda释放数组
sp.reset();
string *koo = new string[10];
//string *iop=koo; //上面这种是无法初始化string *;必须说明维度,但new就可以
_connect_s("你是", "?", koo); //&koo就相当于koo,也是这个数组的首地址,其实传参传的就是首地址
//因为形参我写的有问题,是*o[];其实就是o指向string指针的数组,即里面存的是指针
//我现在改一下
cout << (koo)[0];
std::system("pause");
}
void _connect_s(const string &p, const string &p1,string *o) //string o[]代表的是string *,指的是o的首地址
{ //而string (*o)[]代表的是一个数组指针,它指向一个数组
*(o) = p + p1; //但这样string (*koo)[10]传不进来,一个是string (*)[10]
//一个是string (*)[],二者不匹配,后面会学到传任意大小的数组,
//若想可行,就必须设形参是string (*)[10]
//还有一种,就是如果传任意大小的东西,就是实参不用一个数组的指针,而是直接传其首地址进去,
//其实也是可以修改的
}
void deleter(int *ptr)
{
delete ptr;
ptr = nullptr;
cout << "delete pointer" << endl;
}
bool b() {
int *p = new int;
return p; //我也不知道作何解释,但是能编译出来
}
vector<int> *exchange(const vector<int> put)
{
vector<int> *p = new vector<int>(put);
return p; //p虽然没了,但它指向得内存还在
}
shared_ptr<vector<int>> my_exchange(const vector<int> put)
{
shared_ptr<vector<int>> p = make_shared<vector<int>>(put); //用了智能指针
return p; //此时p是智能指针,当返回p时,p被销毁,p的引用计数减为0,
//但返回p时有别的对象引用了p;因此p所指的那片内存还在;
//直到最后一个引用那片内存的对象被销毁为止;
shared_ptr<int> goo(new int(42)); //引用计数为1
int *yu = goo.get(); //此时这个指针也指向那片内存,但不是智能指针,它被释放,则那片内存也没了
{ //新程序块
//两个独立的shared_ptr指向相同的内存
shared_ptr<int>(yu); //此时yu是一个智能指针了
} //但yu的那个智能指针是局部的,也引用计数为1;程序酷爱结束,它就销毁了,从而那片内存也被销毁
int foo = *goo; //错误,此时那片内存已经被释放了
}
struct destination;
struct connection{};
//connection connect(destination *);
//void disconnect(connection);
//void f(destination &f)
//{
// connection op = connect(&f);
// shared_ptr<connection> k(&op, end_connect); //当f退出时,(即使是异常而退出,connection会被正确关闭)
// shared_ptr<connection> k1(&op, [](connection *p) {disconnect(*p); }); //lambda
//}
//
//void end_connect(connection *y) //关闭函数
//{
// disconnect(*y);
//
//};
/*------------------小纠结-----------------*/
#include<iostream>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
using namespace std;
void _connect_s(const string &p, const string &p1, string *o);
void _connect_j(const string &p, const string &p1, string(*o)[]);
void main()
{
string koo[10];// = new string[10];
string *_new_koo= new string[10];
string(*kop)[10];
//_connect_j("你是", "?", kop); //一个是string (*)[]和string (*)[10]不匹配
_connect_s_pointer("你是", "?", _new_koo);
_connect_s("你是", "?", _new_koo);
_connect_s("你是", "?", koo);
cout << (koo)[0];
system("pause");
}
void _connect_s(const string &p, const string &p1, string &o)
{
*(&o + 2) = p + p1; //第一种是传首地址进去
}
void _connect_s_pointer(const string &p, const string &p1, string *o)
{
*(o + 2) = p + p1; //传指针进去
}
void _connect_j(const string &p, const string &p1, string (*o)[])
{
*(*o + 2) = p + p1; //传指针进去
}