64,683
社区成员
发帖
与我相关
我的任务
分享
#pragma once
#include <vector>
#include <memory>
#include <string>
#include <initializer_list>
using std::vector;
using std::shared_ptr;
using std::string;
using std::initializer_list;
using std::make_shared;
using std::weak_ptr;
template <typename> class BlobPtr; // 友元的前向声明
template <typename T>
class Blob
{
friend class BlobPtr<T>; // 声明为Blob的友元类, 一对一的关系
public:
using value_type = T;
using size_type = typename vector<T>::size_type;
//! constructor
Blob() : data(make_shared<vector<T>>()) {}
Blob(initializer_list<T> il) : data(make_shared<vector<T>>(il)) {}
//! add element
void push_back(const T& rhs);
void push_back(T&& rhs);
//! remove the tail element
void pop_back();
//! get size
size_type size() const;
//! empty
bool empty() const;
//! element access
const T& back() const;
T& back();
const T& operator[](size_type index) const;
T& operator[](size_type index);
private:
shared_ptr<vector<T>> data;
void check(size_type index, const string& msg) const;
};
template <typename T>
class BlobPtr
{
//! constructor
BlobPtr() : wptr(nullptr), curr(0) {}
// 这里使用Blob中的私有变量
BlobPtr(Blob<T>& blob, size_t i = 0) : wptr(blob.data), curr(i) {}
private:
weak_ptr<vector<T>> wptr;
size_t curr;
shared_ptr<vector<T>> check(size_t index, const string& msg) const;
};
template <typename T>
const T& Blob<T>::operator[](size_type index) const
{
check(index, "out of range");
return (*data)[index];
}
template <typename T>
T& Blob<T>::operator[](size_type index)
{
check(index, "out of range");
return (*data)[index];
}
template <typename T>
void Blob<T>::check(size_type index, const string& msg) const
{
if (data->size() <= index)
{
throw std::out_of_range(msg);
}
}
template <typename T>
const T& Blob<T>::back() const
{
check(0, "out of range");
return data->back();
}
template <typename T>
T& Blob<T>::back()
{
check(0, "out of range");
return data->back();
}
template <typename T>
void Blob<T>::push_back(const T& rhs)
{
data->push_back();
}
template <typename T>
void Blob<T>::push_back(T&& rhs)
{
data->push_back(std::move(rhs));
}
template <typename T>
typename Blob<T>::size_type Blob<T>::size() const
{
return data->size();
}
template <typename T>
void Blob<T>::pop_back()
{
data->pop_back();
}
template <typename T>
bool Blob<T>::empty() const
{
return data->empty();
}
template <typename T>
shared_ptr<vector<T>> BlobPtr<T>::check(size_t index, const string& msg) const
{
auto ret = wptr.lock();
if (!ret) throw runtime_error("unbound Blob object");
if (index >= ret->size()) throw out_of_range(msg);
return ret;
}
#include "Exercise16.12.h"
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
int main(int argc, char ** argv)
{
Blob<int> iBlob = {1, 2, 3, 4, 5, 6};
cout << iBlob[2] << endl;
iBlob[2] = 5;
cout << "iBlob.size() : " << iBlob.size() << endl;
cout << "iBlob.back() : " << iBlob.back() << endl;
iBlob.push_back(7);
cout << "iBlob.size() : " << iBlob.size() << endl;
cout << "iBlob.back() : " << iBlob.back() << endl;
iBlob.pop_back();
cout << "iBlob.size() : " << iBlob.size() << endl;
cout << "iBlob.back() : " << iBlob.back() << endl;
cout << "iBlob.empty() : " << iBlob.empty() << endl;
BlobPtr<int> pBlob(iBlob); // 这一行为什么错呢,我已经声明BlobPtr为Blob的友元了啊
return 0;
}