标签: smart-pointers

为什么operator->手动重载?

如果p->m仅仅是语法糖是不是有意义(*p).m?基本上,operator->我写过的每一个都可以实现如下:

Foo::Foo* operator->()
{
    return &**this;
}
Run Code Online (Sandbox Code Playgroud)

在任何情况下,我想要p->m的意思是什么(*p).m

c++ pointers smart-pointers operator-overloading

15
推荐指数
1
解决办法
465
查看次数

有没有理由使用auto_ptr?

从他的STL书中读到Jossutis对auto_ptr的解释之后,我得到了一个强烈的印象,即我会尝试使用它的任何任务100%失败,因为很多auto_ptr的陷阱之一.

我的问题是:有没有任何真正的生活任务,其中auto_ptr真的很有用,并且适合那里吗?

c++ stl smart-pointers auto-ptr

15
推荐指数
2
解决办法
3765
查看次数

GCC 4.7.2的shared_ptr(模板化)赋值运算符的实现是否存在错误?

我的问题涉及shared_ptrGCC 4.7.2中的赋值运算符模板的实现,我怀疑它包含一个bug.

PREMISE 1:C++ 11标准

这是我正在谈论的赋值运算符模板的签名:

template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
Run Code Online (Sandbox Code Playgroud)

从C++ 11标准(20.7.2.2.3):

"相当于 shared_ptr(r).swap(*this)."

换句话说,赋值运算符模板是根据构造函数模板定义的.构造函数模板的签名如下:

template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
Run Code Online (Sandbox Code Playgroud)

从C++ 11标准(20.7.2.2.1):

"要求:[...]构造函数不应参与重载决策,除非Y*可隐式转换为T*."

PREMISE 2:GCC 4.7.2的实施:

现在GCC 4.7.2的构造函数模板的实现对我来说似乎是正确的(std::__shared_ptr是基类std::shared_ptr):

template<typename _Tp1, typename = 
typename std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
__shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
    : 
    _M_ptr(__r._M_ptr), 
    _M_refcount()
{
    _M_refcount._M_swap(__r._M_refcount);
    __r._M_ptr = 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,GCC 4.7.2的赋值运算符模板的实现如下:

template<typename _Tp1>
__shared_ptr& operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
{
    _M_ptr = __r._M_ptr;
    _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw …
Run Code Online (Sandbox Code Playgroud)

c++ gcc stl smart-pointers c++11

15
推荐指数
2
解决办法
1317
查看次数

使用weak_ptr的观察者模式

我正在尝试Subject观察者模式中编写一个安全类.我想知道使用weak_ptr是否是以下列方式存储IObserver实例的最佳方式:

  • IObserver被释放后无法使用实例.
  • Subject类不抱上IObserver应free'd引用(流逝的听众的问题).
  • Subject类必须是线程安全的.

不幸的是,我们的编码标准说我们不允许使用boost.我想我以前的生活中是一个坏人.幸运的是,我被允许使用C++ 11(Visual Studio 2012附带的内容).

这是一个示例Observer类.

// Observer interface that supports notify() method
class IObserver
{
public:
    virtual void notify() const = 0;
    virtual ~IObserver() {}
};

// Concrete observer implementation that prints a message
class Observer : public IObserver
{
public:
    Observer( const std::string& message) : m_message( message ){}

    void notify() const {
        printf( "%s\r\n", m_message.c_str() …
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers std c++11

15
推荐指数
1
解决办法
3620
查看次数

返回时为什么指针不能自动转换为unique_ptr?

让我通过一个例子提出我的问题.

#include <memory>

std::unique_ptr<int> get_it() {
        auto p = new int;
        return p;
}

int main() {
        auto up ( get_it() );
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

无法编译时出现以下错误:

a.cpp:5:9: error: could not convert ‘p’ from ‘int*’ to ‘std::unique_ptr<int>’
  return p;
         ^
Run Code Online (Sandbox Code Playgroud)

为什么没有从原始指针自动转换为唯一的指针?我应该做什么呢?

动机:我理解使用智能指针清除所有权应该是一种好习惯; 我从某个地方得到一个指针(我拥有),就像int*在这种情况下一样,我(想想我)想要它unique_ptr.


如果您正在考虑评论或添加您自己的答案,请在提案N4029中解决Herbert Sutter关于此问题的论点.

c++ pointers explicit smart-pointers c++11

15
推荐指数
3
解决办法
6218
查看次数

为什么shared_ptr不允许直接赋值

所以在使用时shared_ptr<Type>你可以写:

shared_ptr<Type> var(new Type());
Run Code Online (Sandbox Code Playgroud)

我想知道为什么他们不允许更简单和更好(imo):

shared_ptr<Type> var = new Type();
Run Code Online (Sandbox Code Playgroud)

而不是要实现这样的功能,您需要使用.reset():

shared_ptr<Type> var;
var.reset(new Type());
Run Code Online (Sandbox Code Playgroud)

我习惯于OpenCV Ptr类,它是一个智能指针,允许直接赋值,一切正常

c++ smart-pointers shared-ptr c++11

15
推荐指数
5
解决办法
1306
查看次数

为什么以及何时需要提供自己的删除器?

为什么以及何时需要提供自己的删除器?关键字不delete足够吗?

如果您使用智能指针来管理分配的内存以外的资源new,请记住传递删除器.


更新:

正如在评论中被问到的那样,我不清楚引用的文本和示例的原因是我在想某些东西是错误的,这是因为我一直在考虑智能指针只是为了动态内存管理而发明的.所以这个例子使用智能指针管理非动态内存让我感到困惑.

老人的一个很好的解释:

智能指针根本不关心动态内存本身.它只是一种在需要时跟踪某些东西的方法,并在它超出范围时销毁它.提到文件句柄,网络连接等的要点是指出它们不是动态内存,但智能指针可以管理它们就好了.


C++ Primer 5th采用伪网络连接(不定义析构函数)来说明.

坏:

struct destination; // represents what we are connecting to
struct connection; // information needed to use the connection
connection connect(destination*); // open the connection
void disconnect(connection); // close the given connection
void f(destination &d /* other parameters */)
{
// get a connection; must remember to close it when done
connection c = connect(&d);
// use the connection
// if we …
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers

15
推荐指数
2
解决办法
1899
查看次数

如果没有更多引用,如何从缓存中删除(非侵入式)智能指针?

由于我的noob声誉,我无法回复此主题,特别是接受的答案:

我从未使用过boost :: intrusive智能指针,但如果你使用shared_ptr智能指针,你可以使用weak_ptr对象作为缓存.

当系统决定释放内存时,那些weak_ptr指针不算作引用,但只要该对象尚未被删除,它就可用于检索shared_ptr.

这当然是一个直观的想法,但是,C++标准不支持weak_ptrs的比较,因此它不能用作关联容器的键.这可以通过为weak_ptrs实现比较运算符来规避:

template<class Ty1, class Ty2>
    bool operator<(
        const weak_ptr<Ty1>& _Left,
        const weak_ptr<Ty2>& _Right
    );
Run Code Online (Sandbox Code Playgroud)

这个解决方案的问题是

(1)比较运算符必须获得每次比较的所有权(即从weak_ptr refs创建shared_ptrs)

(2)当管理资源的最后一个shared_ptr被破坏时,weak_ptr不会从缓存中删除,但是过期的weak_ptr会保留在缓存中.

对于(2),我们可以提供自定义析构函数(DeleteThread),但是,这将需要再次从要删除的T*创建weak_ptr,然后可以使用它从缓存中擦除weak_ptr.

我的问题是,如果有更好的方法使用智能指针缓存(我使用VC100编译器,没有提升),或者我根本没有得到它?

干杯,丹尼尔

c++ caching smart-pointers shared-ptr weak-ptr

14
推荐指数
1
解决办法
1581
查看次数

将所有权从std :: shared_ptr移至std :: unique_ptr

我有一个类A,其字段类型为std::unique_ptr:

class A
{
public:
   std::unique_ptr pointer;
// class body
};
Run Code Online (Sandbox Code Playgroud)

在代码中的某个地方,我使用很少的std::shared_ptrs指向同一个对象.现在我想要实现的是std::unique_ptr在我的班级中将所有权转移到这个,这样如果所有的shared_ptrs都将被销毁,只要这个unique_ptr将保持活着,我的对象将保持活着.

我的问题是 - 是否有可能将所有权转移std::shared_ptrstd::unique_ptr,如果是,我该怎么做?

c++ smart-pointers shared-ptr unique-ptr

14
推荐指数
1
解决办法
1万
查看次数

类指针类和 - >*运算符

我最近遇到了将指针指向成员应用于迭代器指定的对象的需要.我尝试过自然语法:

ite->*ptr = 42;
Run Code Online (Sandbox Code Playgroud)

令我沮丧的是,它没有编译.迭代器不会过载operator->*,但更令人惊讶的是智能指针也不会.我需要诉诸以下笨拙:

(*ite).*ptr = 42;
Run Code Online (Sandbox Code Playgroud)

试验(参见下面的实例)已经表明,对于自定义类,对于指向成员的指针和指向成员函数的指针,这样的语法似乎是可以实现的,至少从C++ 14开始.

因此:

  • 标准类指针类不会过载operator->*,还是仅仅是一种疏忽?
  • operator->*在定义类似指针的类时,我应该重载,还是同样的理由适用于我?

实例 - 什么是编译,什么不编译,以及自定义类的概念验证.

c++ iterator smart-pointers operator-overloading c++14

14
推荐指数
1
解决办法
333
查看次数