Comments (2)
对于我们自己的SharedPtr,无法对weak_ptr赋值,这里我们能怎么做
weak_ptr& operator=( const weak_ptr& r ) noexcept; | (1) | (C++11 起)
-- | -- | --
template< class Y > weak_ptr& operator=( const weak_ptr<Y>& r ) noexcept; | (2) | (C++11 起)
template< class Y > weak_ptr& operator=( const shared_ptr<Y>& r ) noexcept; | (3) | (C++11 起)
weak_ptr& operator=( weak_ptr&& r ) noexcept; | (4) | (C++14 起)
template< class Y > weak_ptr& operator=( weak_ptr<Y>&& r ) noexcept;
from cppprimer.
I remove the iterator
#include <vector>
#include <memory>
#include <string>
#include <list>
#include <iostream>
#include <initializer_list>
#include <exception>
#include <algorithm>
template <class T>
class SharedPtr
{
using DelFuncPtr = void (*)(T *);
private:
T *ptr_ = nullptr;
size_t *count_ptr_ = nullptr;
DelFuncPtr del_ = nullptr;
public:
SharedPtr(T *ptr = nullptr, DelFuncPtr del = nullptr) : ptr_(ptr), del_(del), count_ptr_(new size_t(ptr_ != nullptr)) {}
SharedPtr(const SharedPtr &s) : ptr_(s.ptr_), del_(s.del_), count_ptr_(s.count_ptr_)
{
++*s.count_ptr_;
}
SharedPtr &operator=(SharedPtr s) //这里使用值传递,会先复制一份
{
//交换自己和临时的,临时的在退出的时候会自动调用析构释放
swap(s);
return *this;
}
void reset(T *ptr = nullptr, DelFuncPtr d = nullptr)
{
auto news = SharedPtr(ptr, d);
swap(news);
}
void swap(SharedPtr &r) noexcept
{
using std::swap;
swap(ptr_, r.ptr_);
swap(count_ptr_, r.count_ptr_);
swap(del_, r.del_);
}
~SharedPtr()
{
if (ptr_ == nullptr)
return;
if (0 == --*count_ptr_)
{
del_ == nullptr ? delete (ptr_) : del_(ptr_);
delete count_ptr_;
}
ptr_ = nullptr;
count_ptr_ = nullptr;
}
T *get() const noexcept
{
return ptr_;
}
size_t use_count() const noexcept
{
return *count_ptr_;
}
T &operator*() const noexcept
{
return *ptr_;
}
T *operator->() const noexcept
{
return ptr_;
}
//检查 *this 是否存储非空指针,即是否有 get() != nullptr
explicit operator bool() const noexcept
{
return get() != nullptr;
}
};
template <typename T>
class Blob;
template <typename T>
bool operator==(const Blob<T> &a, const Blob<T> &b);
template <typename T>
bool operator!=(const Blob<T> &a, const Blob<T> &b);
template <typename T>
bool operator<(const Blob<T> &a, const Blob<T> &b);
template <typename T>
bool operator>(const Blob<T> &a, const Blob<T> &b);
template <typename T>
bool operator<=(const Blob<T> &a, const Blob<T> &b);
template <typename T>
bool operator>=(const Blob<T> &a, const Blob<T> &b);
template <typename T>
class Blob
{
friend bool operator==<T>(const Blob<T> &a, const Blob<T> &b);
friend bool operator!=<T>(const Blob<T> &a, const Blob<T> &b);
// clang-format off
friend bool operator< <T>(const Blob<T> &a, const Blob<T> &b);
friend bool operator> <T>(const Blob<T> &a, const Blob<T> &b);
// clang-format on
friend bool operator<=<T>(const Blob<T> &a, const Blob<T> &b);
friend bool operator>=<T>(const Blob<T> &a, const Blob<T> &b);
// 以下两个应该是为了外部方便获取类型
typedef T value_type;
typedef typename std::vector<T>::size_type size_type;
private:
SharedPtr<std::vector<T>> data;
void check(size_type i, const std::string &msg) const;
public:
Blob() : data(new std::vector<T>()) {}
// 16.24
template <typename type_it>
Blob(type_it a, type_it b) : data(new std::vector<T>(a, b)) {}
Blob(const Blob<T> &s) : data(new std::vector<T>(*s.data)) {}
Blob(Blob<T> &&a) noexcept : data(std::move(a.data)) {}
Blob &operator=(const Blob<T> &s);
Blob &operator=(Blob<T> &&) noexcept;
Blob(std::initializer_list<T> il) : data(new std::vector<T>(il)) {}
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(T &val) { data->push_back(val); };
void push_back(const T &val) { data->push_back(std::move(val)); }
void pop_back();
T &back();
const T &back() const;
T &front();
const T &front() const;
T &operator[](size_type i);
const T &operator[](size_type i) const;
void print(std::ostream &o);
};
template <typename T>
Blob<T> &Blob<T>::operator=(const Blob<T> &s)
{
data = new std::vector<T>(*s.data);
return *this;
}
template <typename T>
Blob<T> &Blob<T>::operator=(Blob<T> &&s) noexcept
{
if (this != s)
{
data = std::move(s.data);
s.data = nullptr;
}
return *this;
}
template <typename T>
void Blob<T>::print(std::ostream &o)
{
for (auto ch : (*data))
o << ch << ",";
o << std::endl;
}
template <typename T>
void Blob<T>::check(size_type i, const std::string &msg) const
{
if (i >= size())
{
throw std::out_of_range(msg);
}
}
template <typename T>
void Blob<T>::pop_back()
{
check(0, "empty to pop_back");
data->pop_back();
}
template <typename T>
T &Blob<T>::back()
{
check(0, "Get empty Back()");
return data->back();
}
template <typename T>
const T &Blob<T>::back() const
{
check(0, "Get empty Back()");
return data->back();
}
template <typename T>
T &Blob<T>::front()
{
check(0, "Get empty front()");
return data->front();
}
template <typename T>
const T &Blob<T>::front() const
{
check(0, "Get empty front()");
return data->front();
}
template <typename T>
T &Blob<T>::operator[](size_type i)
{
check(i, "Get [" + std::to_string(i) + "]");
return data->at(i);
}
template <typename T>
const T &Blob<T>::operator[](size_type i) const
{
check(i, "Get [" + std::to_string(i) + "]");
return data->at(i);
}
//****************************************************************************
template <typename T>
bool operator==(const Blob<T> &a, const Blob<T> &b)
{
return (*a.data == *b.data);
}
template <typename T>
bool operator!=(const Blob<T> &a, const Blob<T> &b)
{
return !(a == b);
}
template <typename T>
bool operator<(const Blob<T> &a, const Blob<T> &b)
{
return std::lexicographical_compare(a.data->begin(), a.data->end(), b.data->begin(), b.data->end());
}
template <typename T>
bool operator>(const Blob<T> &a, const Blob<T> &b)
{
return (b < a);
}
template <typename T>
bool operator<=(const Blob<T> &a, const Blob<T> &b)
{
return !(b > a);
}
template <typename T>
bool operator>=(const Blob<T> &a, const Blob<T> &b)
{
return !(a < b);
}
int main(int argc, const char **argv)
{
Blob<std::string> blob_s({"1", "2"});
blob_s.print(std::cout);
while (1)
;
return 0;
}
from cppprimer.
Related Issues (20)
- Wording is wrong for exercise 2.10 HOT 2
- about 16.2.7 HOT 2
- Exercise 7.36
- Exercise 6.53
- Exercise 5.3 correct answer HOT 1
- Ex 6_8 HOT 1
- Ex 6_9 (added #include "fact.cpp")
- Ex 6_10 (added "return 0;")
- Exercise 13.37
- Answer to Exercises 3.37 is not entirely true.
- Ex16.49
- The new soulution of Exercise 5.12
- Ex.7.53 will not compile under the C++14 standard
- #include<exception>
- ex7_22.h 'class' instead of 'struct'
- Bug report exercise 16.12
- An error in exercise 16.28, in file <unique_pointer.h>
- Small modification for answer of Exercise 3.9 - mention `s` is a empty string
- Exercise 9.28(The loop may not stop)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cppprimer.