Talk cheap, It's code:
#include "vld.h"
#define _CRTDBG_MAP_ALLOC
#include
#include
#include
#include
#include
#include
using namespace std;
class StrBlobPtr;
class StrBlob
{
public:
friend class StrBlobPtr;
typedef shared_ptr> shared_strVecP;
typedef vector::size_type size_type;
StrBlob ();
StrBlob (initializer_list il);
size_type size () const { return data->size (); }
bool empty () const { return data->empty (); }
//append & delete
void push_back (const string &t) { data->push_back (t); }
void pop_back ();
//call elements
string& front ();
string& back ();
private:
shared_strVecP data;
//if input invailed, throw exception
void check (size_type query_pos, const string &msg) const
{
try {
if (query_pos >= data->size ())
throw out_of_range (msg);
}
catch (out_of_range err) {
cout << err.what () << endl;
}
}
};
StrBlob::StrBlob () :data (make_shared > ()) {}
StrBlob::StrBlob (initializer_listil) : data (make_shared> (il)) {}
string& StrBlob::front ()
{
//if vector is empty, throw exception
check (0, "front on empty StrBlob");
return data->front ();
}
string& StrBlob::back ()
{
//if vector is empty, throw exception
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:
typedef shared_ptr> shared_strVecP;
StrBlobPtr () :pos (0) {}
StrBlobPtr (StrBlob &a, size_t sz = 0) :wptr (a.data), pos (sz) {}
StrBlobPtr& incr ();
string& deref ()const;
private:
shared_strVecP check (size_t, const string&)const;
weak_ptr>wptr;
size_t pos;
};
shared_ptr> StrBlobPtr::check (size_t query_pos, const string &msg)const
{
typedef shared_ptr> shared_strVecP;
auto ret = wptr.lock ();
try {
if (!ret)
throw runtime_error ("unbound StrBlobPtr!");
if (query_pos >= ret->size ())
throw out_of_range (msg);
}
catch (runtime_error err) {
cout << err.what () << endl;
}
catch (out_of_range err) {
cout << err.what () << endl;
}
return ret;
}
string& StrBlobPtr::deref ()const
{
auto p = check (pos, "dereference past end");
return (*p)[pos];
}
StrBlobPtr& StrBlobPtr::incr ()
{
check (pos, "incerement past end of StrBlobPtr");
++pos;
return *this;
}
int main (int argc, char* argv[])
{
std::ios::sync_with_stdio (false);
size_t times = 0;
string word;
StrBlob blob;
while (cin >> word) {
blob.push_back (word);
++times;
}
StrBlobPtr blob_ptr (blob);
for (size_t i = 0; i < times; ++i) {
cout << blob_ptr.deref () << " ";
blob_ptr.incr ();
cout << endl;
}
system ("pause");
return 0;
}
奇怪的是, VLD检查不出内存泄漏, 但使用VS2013自带的检测机制却显示内存泄漏, 希望以后可以得到答案.