标签: weak-ptr

有没有办法使成员函数不能从构造函数中调用?

我有使用的成员函数(方法)

std::enable_shared_from_this::weak_from_this() 
Run Code Online (Sandbox Code Playgroud)

简而言之:weak_from_this返回weak_ptr这个。一个警告是它不能从构造函数中使用。如果有人使用继承的类的构造函数中的函数,则该函数weak_from_this将返回expired weak_ptr。我通过断言检查它是否未到期来进行防范,但这是运行时检查。

有没有一种方法可以在编译时进行检查?

c++ constructor shared-ptr weak-ptr c++17

21
推荐指数
2
解决办法
1493
查看次数

绑定到weak_ptr

有没有办法将std :: bind绑定到std :: weak_ptr?我想存储一个"弱函数"回调,当被调用者被销毁时,它会自动"断开连接".

我知道如何使用shared_ptr创建一个std :: function:

std::function<void()> MyClass::GetCallback()
{
    return std::function<void()>(std::bind(&MyClass::CallbackFunc, shared_from_this()));
}
Run Code Online (Sandbox Code Playgroud)

但是返回的std :: function使我的对象永远保持活着.所以我想将它绑定到weak_ptr:

std::function<void()> MyClass::GetCallback()
{
    std::weak_ptr<MyClass> thisWeakPtr(shared_from_this());
    return std::function<void()>(std::bind(&MyClass::CallbackFunc, thisWeakPtr));
}
Run Code Online (Sandbox Code Playgroud)

但那不编译.(std :: bind将不接受weak_ptr!)有没有办法绑定到weak_ptr?

我已经找到了关于这个的讨论(见下文),但似乎没有标准的实现.存储"弱功能"的最佳解决方案是什么,特别是如果Boost不可用?


讨论/研究(所有这些都使用Boost并且没有标准化):

c++ bind callback weak-ptr std-function

18
推荐指数
2
解决办法
8553
查看次数

std :: unique_ptr vs std :: shared_ptr vs std :: weak_ptr vs std :: auto_ptr vs raw pointer

与使用原始指针的类似(但不限于)某些高级技术相比,每个智能指针的等效用途是什么?

我的理解很少,但我可以收集到:

  • 原始指针:只有当你真的,真的,真的,真的,知道你正在做什么并且在界面后面仔细隐藏用法时才使用.
  • std :: auto_ptr:过时从不使用.
  • std :: unique_ptr:在赋值时转移所有权的Singleton指针.
  • std :: shared_ptr:引用计数指针,该指针在赋值时不转移所有权,但会增加其引用计数.当所有引用都离开范围或明确地调用std::shared_ptr::reset底层时deallocator.
  • std :: weak_ptr:std::shared_ptr不增加引用计数的子类型,当其父级std::shared_ptr不再存在时无效.可能会返回无效的引用.使用前请务必检查.

RAW指针等效示例

引用计数,缓存实现: std::map<std::string, std::pair<long, BITMAP*> > _cache;

拥有所有权的单身人士:

class Keyboard {
public:
//...
    static Keyboard* CreateKeyboard();
    ~Keyboard();
//...
private:
//...
    Keyboard();
    static Keyboard* _instance;
//...
};
Run Code Online (Sandbox Code Playgroud)

聚合容器,无所有权:空间分区图和树,迭代容器等.

复合容器,所有权:大型对象.

- 编辑 -

在我工作的时候,我遇到了一个有趣的案例,DeadMG指出智能指针应该被用作简单的抽象来处理资源管理; 那些在声明点无法在堆上创建但必须在以后创建的文件范围对象呢?

c++ auto-ptr shared-ptr weak-ptr unique-ptr

18
推荐指数
1
解决办法
9855
查看次数

weak_ptr,make_shared和内存释放

a的控制块shared_ptr保持活动,同时存在至少一个weak_ptr存在.如果创建共享指针make_shared,则意味着保持分配对象的整个内存.(对象本身被正确销毁,但由于控件块和对象的内存分配在一个块make_shared中,因此它们只能一起解除分配.)

我的理解是否正确?

看起来这种行为代表了一个问题,例如在着名的"缓存示例"中.对象的内存将永远分配.

这在任何实际情况下都是一个问题吗?应该shared_ptr在这种情况下使用构造函数创建(大对象和意图使用weak_ptrs)?

c++ shared-ptr weak-ptr make-shared c++11

18
推荐指数
1
解决办法
1685
查看次数

为什么shared_ptr的引用计数对象需要跟踪指向该对象的weak_ptrs的数量?

您好我正在阅读本文档和其他一些关于C++的文档shared_ptr,他们似乎都建议除了shared_ptr指向已分配对象的数量之外,引用计数对象还必须跟踪weak_ptr指向该对象的指针数量.我的问题是为什么?根据我的理解,weak_ptr是非拥有的,因此如果shared_ptr指向对象的计数达到零,则可以删除该对象.这就是为什么有时我们需要使用expired来检查a指向的对象的可用性weak_ptr.你能解释一下需要跟踪weak_ptrs 数的原因吗?

为什么我们这里需要弱计数? 在此输入图像描述

c++ shared-ptr weak-ptr c++11

17
推荐指数
2
解决办法
1943
查看次数

为什么我不能将nullptr转换为weak_ptr <>

class MyClass {
public:
     MyClass(std::weak_ptr<MyClass> parent){}
}
Run Code Online (Sandbox Code Playgroud)

我想做这个:

auto newInstance = std::make_shared<MyClass>(nullptr);
Run Code Online (Sandbox Code Playgroud)

或者weak_ptr参数的默认值为null,例如:

void function(int arg,std::weak_ptr<MyClass> obj = nullptr);
Run Code Online (Sandbox Code Playgroud)

但是,我需要的是这样做:

auto newInstance = std::make_shared<MyClass>(std::shared_ptr<MyClass>(nullptr));
Run Code Online (Sandbox Code Playgroud)

这是为什么?

c++ null casting shared-ptr weak-ptr

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

对象dtor中的`weak_ptr :: expired`行为

请考虑以下代码:

#include <iostream>
#include <memory>
using namespace std;

class T;

std::weak_ptr<T> wptr;

class T
{
public:
    T() {  }
    ~T() {
        std::cout << "in dtor" << std::endl;
        std::cout << (wptr.expired() ? "expired" : "not expired") << std::endl;
    }
};

int main() {
    {
        auto ptr = std::make_shared<T>();
        wptr = ptr;
        std::cout << (wptr.expired() ? "expired" : "not expired") << std::endl;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这段代码中,我试图找出weak_ptrs在对象销毁阶段是否过期.看来是这样.输出是:

not expired
in dtor
expired
Run Code Online (Sandbox Code Playgroud)

我用gcc-5.1和ideone.

现在,我有另一个问题.我找不到任何文档说明这是标准行为.难道是保证这样的工作方式,始终

c++ shared-ptr weak-ptr c++11 c++14

16
推荐指数
3
解决办法
1029
查看次数

如何检查weak_ptr是否为空(未分配)?

有没有办法区分分配的(可能已过期的)weak_ptr和未分配的weak_ptr.

weak_ptr<int> w1;
weak_ptr<int> w2 = ...;
Run Code Online (Sandbox Code Playgroud)

我理解以下检查未分配或到期,但有没有(更便宜?)检查只有非转让?

if (!w.lock()) { /* either not assigned or expired */ }
Run Code Online (Sandbox Code Playgroud)

c++ weak-ptr c++11

16
推荐指数
2
解决办法
6399
查看次数

关于weak_ptr的线程安全性

std::shared_ptr<int> g_s = std::make_shared<int>(1);
void f1()
{
    std::shared_ptr<int>l_s1 = g_s; // read g_s
}

void f2()
{
    std::shared_ptr<int> l_s2 = std::make_shared<int>(3);
    std::thread th(f1);
    th.detach();
    g_s = l_s2; // write g_s
}
Run Code Online (Sandbox Code Playgroud)

关于上面的代码,我知道不同的线程读取和写入相同的shared_ptr导致竞争条件.但是怎么样weak_ptr?下面的代码中是否有竞争条件?(我的平台是Microsoft VS2013.)

std::weak_ptr<int> g_w;

void f3()
{
    std::shared_ptr<int>l_s3 = g_w.lock(); //2. here will read g_w
    if (l_s3)
    {
        ;/.....
    }
}

void f4()
{
    std::shared_ptr<int> p_s = std::make_shared<int>(1);
    g_w = p_s;

    std::thread th(f3);
    th.detach();
    // 1. p_s destory will motify g_w (write g_w)
}
Run Code Online (Sandbox Code Playgroud)

c++ multithreading weak-ptr c++11

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

可以将过期的weak_ptr与未初始化的weak_ptr区分开来吗?

例如:

std::weak_ptr<int> wp1(std::make_shared<int>());
std::weak_ptr<int> wp2;

assert(PointsToValidOrExpiredObject(wp1));
assert(!PointsToValidOrExpiredObject(wp2));
Run Code Online (Sandbox Code Playgroud)

这样的功能可能吗?

用例:类的构造函数std::weak_ptr<Foo>作为依赖项.传递过期的对象是可以的(可能在某些工作流程中发生),但传递null意味着程序员忘记了某些事情.我想测试它作为构造函数的参数验证的一部分.

c++ weak-ptr c++11

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