C++基础::shared_ptr 编程细节(一)
来源:互联网 发布:视频观看软件 编辑:程序博客网 时间:2024/06/07 20:41
C++基础::shared_ptr 编程细节(一)
C++基础::shared_ptr 编程细节(二)
C++基础::shared_ptr 编程细节(三)
智能指针是c++ 中管理资源的一种方式,用智能指针管理资源,不必担心资源泄露,将 c++ 程序员从指针和内存管理中解脱出来。
shared_ptr 的两面性
shared_ptr 型智能指针对象的本质是类实例;
所以允许
.+成员函数
的调用方式(这里的成员函数是 shared_ptr 作为类实例所具有的成员函数),比如一个shared_ptr
最为类实例的成员函数:- .use_count()
- .get()
- .reset()
- .unique()
- …
含义上作为智能指针的一面
所以允许
->成员函数
的调用方式(这里的成员函数为智能指针所维护的真实对象所具有的成员函数)。
shared_ptr 的副作用
shared_ptr:一种智能指针,本意封装原生指针(new 出来的堆对象),实现指针的类型安全,然而,见名知意,它是共享型指针,即允许多个shared_ptr“指向”同一个对象,当我们在某些情况下不需要这一看似美好的性质时,该如何处理呢。
class Item{private: std::string _name; float _price;public: Item(const std::string& name, float price):_name(name), _price(price){} float getPrice() const { return _price;} void setPrice(float price) { _price = price;} Item* clone() const { return new Item(*this);} };// 单纯为了演示的需要,并无实际的意义class A{public: A(const std::shared_ptr<Item>& obj):_obj(obj){} const std::shared_ptr<Item>& get() const { return _obj;}private: std::shared_ptr<Item> _obj;};int main(int, char**){ std::shared_ptr<Item> item1(new Item("C++", 20.)); A a(item1); // 此时查看item1的引用次数: std::cout << item1.use_count() << std::endl; // 2 // 如果使用对象a对内部的_obj进行修改,会同步到item1中 a.get()->setPrice(30.); std::cout << item1->getPrice() << std::endl; // 这时我们创建另外一个A对象 A b(a); // 这时如果不对A的拷贝构造进行重载的话,b也会持有一份对item1对象的引用 std::cout << item1.use_count() << std::endl; // 3 return 0;}
这就是shared_ptr
共享型智能指针的便捷和局限。那么,我们该如何使用拷贝构造时,建立自己独特的副本呢?
我们需要显式地给出A的拷贝构造,避免编译器对拷贝构造的默认实现:
class A{...public: A(const A& other) { _obj = std::shared_ptr<Item>(other.get()->clone()); } }
所以结论是,在一个需被 shared_ptr 封装的类内部给出非常关键 clone() 函数的实现非常关键 ;
Obj* clone() const { return new Obj(*this); }
以 shared_ptr 类类型为容器类型的容器之间的赋值
是继续持有对象的引用,还是一份全新的拷贝;
std::shared_ptr<Item> item1(new Item("C++", 20.5));std::shared_ptr<Item> item2(new Item("Python", 25.5));std::vector<std::shared_ptr<Item>> v1 = {item1, item2};std::vector<std::shared_ptr<Item>> v2 = v1; // 继续持有引用std::cout << item1.use_count() << std::endl; // 3item1->setPrice(30.);std::cout << v2[0]->getPrice() << std::endl;std::vector<std::shared_ptr<Item>> v3;for (size_t i = 0; i < v1.size(); ++i) v3.push_back(std::shared_ptr<Item>(v1[i]->clone())); // 一份全新的拷贝item2->setPrice(35.5);std::cout << v3[1]->getPrice() << std::endl; // 25.5
0 0
- C++基础::shared_ptr 编程细节(一)
- C++基础::shared_ptr 编程细节(二)
- C++基础::shared_ptr 编程细节(三)
- C\C++语言基础细节(一)
- C++基础细节(一)
- Theano编程细节(一)
- Python编程细节(一)
- C编程细节(4)
- shared_ptr(一)
- c语言细节(一)
- Linux-c 编程基础(一)
- objective-c 编程基础(一 基础语法)
- c/c++: 多线程编程基础讲解(一)
- c/c++: 多线程编程基础讲解(一)
- c/c++: 多线程编程基础讲解(一)
- 编程中的细节问题(一)
- C/C++编程细节(一)——你未必知道
- C编程的细节(1)
- 解决github push错误The requested URL returned error: 403 Forbidden while accessing
- KVO
- Python中的random模块
- mongoDB 基本操作,增删改查
- 机器学习笔记_数学基础_4-线性代数
- C++基础::shared_ptr 编程细节(一)
- 【Unity开发】NGUI,UGUI按钮监听的动态添加与移除
- Linux图片处理工具-GraphicsMagick
- 32位和64位系统区别及字节对齐
- hdu4815Little Tiger vs. Deep Monkey 概率dp
- POJ 2001 Shortest Prefixes (字典树模拟切割)
- MongoDB C# / .NET Driver 中IMongoQuery的内部实现Query的用法
- iOS 图片 按钮 切圆角
- UIlabel多行文字自动换行 (自动折行)