我的问题是:是否存在share_ptr引用计数为0,而weak_ptr引用计数不为0的情况?
C++中make_shared和普通shared_ptr的区别
引用这个线程,显示如果一个shared_ptr是由weak_ptr创建的,make_shared并且有weak_ptr,它的控制块将是活动的,until shared_ptr和weak_ptr的引用计数都为0。它说:
必须有一种方法让weak_ptr 确定托管对象是否仍然有效(例如锁)。他们通过检查拥有托管对象(存储在控制块中)的shared_ptr 数量来做到这一点。结果是控制块一直处于活动状态,直到共享指针计数和弱指针计数都达到 0。
我做了一个快速测试。我希望shared_ptr创建的make_shared,如果有weak_ptr指向它,control block在shared_ptr被破坏后它仍然会保存。
#include<memory>
#include<iostream>
using namespace std;
struct My {
int m_i;
My(int i) : m_i(i) { cout << "My ctor:" << m_i << '\n';}
~My() { cout << "My ctor:" << m_i << '\n';}
};
weak_ptr<My> wp1, wp2;
int main() {
{
auto sp1 = shared_ptr<My>(new My(30));
wp1 = weak_ptr<My>(sp1);
}
cout<< wp1.use_count() << endl;
{
auto sp2 = make_shared<My>(40); …Run Code Online (Sandbox Code Playgroud) 我正在尝试将listof转换shared_ptr为 int 。当我尝试指向列表中的某个元素时,如果我有一个shared_ptr指向该元素的对象,则会失败。
#include <iostream>
#include <list>
using namespace std;
class A
{
public:
A(){};
shared_ptr<int> p;
};
int main()
{
list<shared_ptr<int>> l;
l.push_back(make_shared<int>(1));
cout << "counts to shared pointer: " << l.back().use_count() << endl;
/* This works */
A a1;
a1.p = l.back();
cout << "counts: " << l.back().use_count() << endl;
/* This does not work */
shared_ptr<A> a2;
a2->p = l.back();
cout << "counts: " << l.back().use_count() << endl;
}
Run Code Online (Sandbox Code Playgroud)
输出:
counts: …Run Code Online (Sandbox Code Playgroud) 从std::shared_ptr 线程安全等文章中,我知道 std::shared_ptr 的控制块按标准保证是线程安全的,而指向的实际数据本质上不是线程安全的(即,它是对我来说,作为用户,做到这一点)。
我在研究中未能找到如何保证这一点的答案。我的意思是,具体使用什么机制来确保控制块是线程安全的(因此对象只被删除一次)?
我问这个问题是因为我正在将 newlib-nano C++ 库与 FreeRTOS 一起用于嵌入式系统。这两者本质上并不是为了相互协作而设计的。由于我从未编写过任何代码来确保控制块是线程安全的(例如,没有关键部分或互斥体的代码),因此我只能假设它实际上可能不是 FreeRTOS 线程安全的。
我组建了一个小类,继承自std::enable_shared_form_this如下:
class Foo : std::enable_shared_from_this<Foo>
{
Foo() = default();
public:
[[nodiscard]] static auto getInstance()
{
static auto f = std::shared_ptr<Foo>(new Foo());
return f;
}
stream construct()
{
return stream{ shared_from_this() };
}
};
Run Code Online (Sandbox Code Playgroud)
每当我打电话时construct(),bad_weak_ptr exception都会被抛出。谁能解释为什么我会观察到这种行为?
编译:Apple clang 版本 13.0.0 (clang-1300.0.29.30)
目标:arm64-apple-darwin21.5.0
让我们考虑下面的代码:
class A {
string a;
public A(string a) : a(a) { }
};
class B : public A {
public B(string a) : A(a) { }
};
int main() {
std::shared_ptr<A> x1 = std::make_shared<B>("x");
std::shared_ptr<A> x2 = std::make_shared<B>("x");
A* atom1 = x1.get();
A* atom2 = x2.get();
A* atom1X = std::make_shared<B>("x").get();
A* atom2X = std::make_shared<B>("x").get();
bool condition1 = (atom1 == atom2);
bool condition2 = (atom1X == atom2X);
}
Run Code Online (Sandbox Code Playgroud)
结果令我惊讶,因为条件 1 为假,但条件 2 为真。为什么?你能解释一下这是怎么回事吗?
我正在互联网上进行研究。我想了解它是如何工作的
注意:在发布问题之前,我已经浏览了有关std::bad_weak_errorwhile usingshared_from_this将现有实例的 shared_ptr 传递shared_ptr给另一个方法的现有问题。它们都与此类似:
shared_from_this()std::enable_shared_from_this<>public。以下是重现该错误的示例代码:
#include <iostream>
#include <memory>
class ILogger {
public:
virtual ~ILogger() {}
virtual void Log() = 0;
};
class LogManager;
class Logger : public ILogger {
public:
Logger(std::shared_ptr<LogManager> logManager)
: m_logManager(logManager)
{
}
void Log() override
{
std::cout << "Dump logs";
}
private:
std::shared_ptr<LogManager> m_logManager;
};
class ILogManager {
public:
virtual ~ILogManager() {}
virtual std::shared_ptr<ILogger> GetLogger() = 0;
};
class LogManager : public ILogManager, public …Run Code Online (Sandbox Code Playgroud) 我正在阅读thread_pool的开源代码
它显示
// add new work item to the pool
template<class F, class... Args>
auto ThreadPool::enqueue(F&& f, Args&&... args)
-> std::future<typename std::result_of<F(Args...)>::type>
{
using return_type = typename std::result_of<F(Args...)>::type;
auto task = std::make_shared< std::packaged_task<return_type()> >(
std::bind(std::forward<F>(f), std::forward<Args>(args)...)
);
std::future<return_type> res = task->get_future();
{
std::unique_lock<std::mutex> lock(queue_mutex);
// don't allow enqueueing after stopping the pool
if(stop)
throw std::runtime_error("enqueue on stopped ThreadPool");
tasks.emplace([task](){ (*task)(); });
}
condition.notify_one();
return res;
}
Run Code Online (Sandbox Code Playgroud)
据我所知, std::packaged_task是唯一可移动的对象,那么shared_ptr 可以task由 组成吗std::packaged_task?因为std::packaged_task永远不可能shared。 …
我搜索了一下但找不到任何正确回答我的问题的东西(我已经读过这个,这个和这个)
我目前正在尝试使用具有多态性的智能指针.
当我尝试使用指向实现的指针创建指向抽象类的智能指针时,即:
std::shared_ptr<Abstract> ptr = std::make_shared(new Implementation);
Run Code Online (Sandbox Code Playgroud)
我的编译器(MSVC2012)显示有关创建Abstract不可能的实例的错误,因为它具有纯虚拟,即使我尝试创建指针Implementation.
在这种情况下,我可能只是使用完全错误的智能指针,但后来我不知道我做错了什么(并且Visual Studio没有强调我提到的行).
我想知道当需要多态时是否可以使用智能指针,如果是,那么必须如何完成.
注意:我知道协方差,以及shared_ptr 不是继承shared_ptr的类型,但认为智能指针会处理这个问题.
编辑:
根据要求,真正的代码行是:
std::shared_ptr<ISpectrometer> ret = std::make_shared<OOSpectrometer>(m_spectroWrapper);
Run Code Online (Sandbox Code Playgroud)
随着OOSpectrometer从抽象类继承ISpectrometer(和m_spectroWrapper简单的参数).
错误MSVC给我(它是法语,所以可能与英语消息不同)是
error C2259: OOSpectrometer : can't instantiate an abstract class due to the following members :
Run Code Online (Sandbox Code Playgroud)
然后它列出了所在的纯虚函数ISpectrometer.
我想从参考更新智能指针。
shared_ptr<My_Toy> my_toy_ptr;
// Something...
void update(shared_ptr<My_Toy> my_toy_ptr, My_Toy& toy){
my_toy_ptr = &toy;
}
Run Code Online (Sandbox Code Playgroud)
...但是他的代码产生了错误。
我该怎么做?
有什么区别:
std::shared_ptr<int> p1 = std::shared_ptr<int>(new int);
Run Code Online (Sandbox Code Playgroud)
和
std::shared_ptr<int> p2 = (std::shared_ptr<int>) new int;
Run Code Online (Sandbox Code Playgroud)
哪个更好?为什么?
c++ ×10
shared-ptr ×10
c++11 ×4
reference ×2
weak-ptr ×2
freertos ×1
list ×1
make-shared ×1
polymorphism ×1