C++11的新特性之shared_ptr和unique_ptr
本篇文章将继续介绍C++11的新特性-智能指针 shared_ptr和unique_ptr。关于所有C++11的重要的改变请参看,
智能指正并不是C++11才引入的,早在C++98/03标准中已经有了auto_ptr。在C++11定义了新的智能指针来替代 std::auto_ptr.
std::auto_ptr在C++11已经不被推荐使用,当然你还可以用,不过在C++17版本中完全移除,也就是如果你编译的时候使用的是 -std=c++17,如果你使用std::auto_ptr,那么gcc会直接告诉你一个编译错误。
关于为什么auto_ptr被deprecated,stackoverflow上面有个帖子
Why is auto_ptr being deprecated?
shared_ptr和unique_ptr是标准模板库的模板类,所以使用的时候要加上它对应的命名空间-std,或者使用前声明
use namespace std;
或者
std::shared_ptr std::unique_ptr
基本用法
例如,定义保存int指针的智能指针,
std::shared_ptr<int> myintptr(new int);
std::unique_ptr<int> myintptr(new int);
class Base{};
class Derived : public Base {};
std::shared_ptr<Base> p = std::make_shared<Derived>();
这里说一下std::make_shared是c++17定义的方法。
那么什么情况下用std::shared_ptr什么情况下使用std::unique_ptr呢
它们的共同之处是开发人员不在需要关心指针所指向的内存的释放问题,当这块内存不在被引用时,那么会被自动释放。区别是,指向同一内存的某一类型的指针的数量的多少,std::unique_ptr只允许一个,而std::shared_ptr允许多个。
std::unique_ptr 最多允许一个,当这个智能指针被销毁时,对应的内存会被自动释放。如果你试图去拷贝一个std::unique_ptr,那么编译器会报错,例如下面的代码就会报错
std::unique_ptr<Base> p(new Base); // 没有问题
std::unique_ptr<Base> p1 = p; // 这里会有编译错误,不能拷贝std::unique_ptr
但是std::unique_ptr支持move语法,所以你可以这样
std::unique_ptr<Base> p(new Base); // 没有问题
std::unique_ptr<Base> p1 = std::move(p); // 没有问题
对于std::shared_ptr,上面的拷贝的那个例子就没有任何问题,
std::shared_ptr<Base> p(new Base); // 没有问题
std::shared_ptr<Base> p1 = p; // 没有问题
类的智能指针变量
如果不能做下面的操作,那么怎么定义一个类的智能指正类成员变量?
std::unique_ptr<Base> p1 = p;
这个就需要用到智能指针的reset()方法
下面是一个例子:
#include <memory>
#include “ClassB.h”
class ClassA
{
public:
ClassA() = default;
virtual ~ClassA() = default;
bool create( void );
ClassA( const ClassA& ) = delete;
ClassA& operate=( const ClassA& ) = delete;
private:
std::unique_ptr m_anotherClassPtr;
}
bool ClassA::create( void )
{
m_anotherClassPtr.reset( new ClassB );
return true;
}
智能指针是否为空
智能指针定义操作符 bool
std::unique_ptr::operator bool
来判断一个指针是否不为空,是不为空,所以如果返回值是true,那么就是该智能指针已经有值,相当于
get()!=nullptr
关于get()后面又解释。
下面是一个例子,
#include <iostream>
#include <memory>
int main () {
std::unique_ptr<int> foo;
std::unique_ptr<int> bar (new int(12));
if (foo) std::cout << "foo points to " << *foo << '\n';
else std::cout << "foo is empty\n";
if (bar) std::cout << "bar points to " << *bar << '\n';
else std::cout << "bar is empty\n";
return 0;
}
获取智能指针所管理的内部指针
C++11定义了
std::unique_ptr::get
来获取智能指针所管理的内部指针
下面是个例子,
|
基类的智能指针转换为子类的智能指针
c++的多态的实现是通过指针或者引用实现。
例如下面的例子
“`C++
class CA
{
};
class CB : public CA
{
};
class CC : public CA
{
};
class CClient
{
private:
shared_ptr<CA> m_pCAInstance;
}
CClient::CClient()
{
m_pCAInstance = std::make_shared<CB>();
}
““
如果m_pCAInstance想调用CB的一个public方法,那么我们就要m_pCAInstance转换成CA,这个需要用dynamic_pointer_cast
std::shared_ptr
先简单写到这里,等有时间了,再进行补充。
参考
http://en.cppreference.com/w/cpp/memory/shared_ptr
http://en.cppreference.com/w/cpp/memory/unique_ptr
版权所有,禁止转载. 如需转载,请先征得博主的同意,并且表明文章出处,否则
按侵权处理.