如何使用 boost::weak_ptr 在构造函数中实现对对象的弱引用?
How to implement a weak reference to an object in a constructor using boost::weak_ptr?
如何在 C++ 中的构造函数中为现有对象创建 boost::weak_ptr?
这是我得到的,但它不起作用,因为共享指针构造函数是错误的。问题是我不想做新任务。我想使用创建 TestCallback 所需的任务,但我只想要对 TestTask 的弱引用,因为 TestTask 拥有 TestCallback,如果它消失,那么 TestCallback 也应该消失。
class TestCallback {
public:
TestCallback(TestTask task);
boost::weak_ptr<TestTask> testTask;
};
//构造函数
TestCallback(TestTask task) {
boost::shared_ptr<DeleteStaticRouteTask> sharedTask(task);
boost::weak_ptr<DeleteStaticRouteTask> weakTask(sharedTask);
m_task = weakTask;
}
//理想调用点
TestTask testTask(DependencyA, DependencyB);
TestCallback testCallback(task);
此功能的大部分已包含在 C++ 标准中。如果你不能使用这样的最新版本,那么 boost 库非常接近相同,你可以在此处将 std::
替换为 boost::
。
要从原始指针创建 shared_ptr
或 weak_ptr
,您必须从 enabled_shared_from_this
派生,例如:
class Foo : public std::enabled_shared_from_this<Foo> // C++11
{
};
...
Foo *ptr = ...;
std::shared_ptr<Foo> a = foo->shared_from_this(); // C++11
std::weak_ptr<Foo> b = foo->weak_from_this(); // C++17
enabled_shared_from_this
会为您的类型增加一点尺寸,但是 make_shared
也会对不使用它的类型增加一点尺寸,所以如果这是一个问题,或者通常为了简单起见,有unique_ptr
(C++11) 更像是原始指针。
尝试从堆栈分配的对象中创建一个通常仍然没有意义,因为 shared_ptr 不会像普通局部变量一样阻止它被删除,实际上可能导致双重删除。你可以做一些技巧,比如给它一个 "no-op" 删除器来解决第二个问题。
在 Foo *ptr
的情况下,您还需要确保它的其他一些 shared_ptr
仍然存在,否则 ptr
可能已经被删除了。
所以答案是不能用弱指针实例化一个对象。下面是一个示例,您可以使用它来实现对象之间的弱引用。
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
class Callback;
class Task: public boost::enable_shared_from_this<Task>
{
public:
Task(Callback& callback)
: m_callback(callback)
{
std::cout << "Task:: Constructor" << std::endl;
}
void delegateMethod() {
std::cout << "Task: delegateMethod" << std::endl;
}
private:
Callback& m_callback;
};
class Callback
{
public:
Callback(){
std::cout << "Callback::Constructor" << std::endl;
};
//You have to set the delegate after Construction
void delegate(const boost::weak_ptr<Task> task) {
std::cout << "Callback:: void delegate(const boost::weak_ptr<Task> task) " << std::endl;
this->m_delegate = task;
}
void delegateSomething() {
std::cout << "Callback::delegateSomething()" << std::endl;
boost::shared_ptr<Task> sharedDelegate = this->m_delegate.lock();
std::cout << "sharedDelegate: " << sharedDelegate << std::endl;
if (sharedDelegate) {
// Use *shared_delegate
std::cout << "Callback::delegateSomething() use delegate" << std::endl;
sharedDelegate->delegateMethod();
}
}
private:
boost::weak_ptr<Task> m_delegate;
};
int main()
{
std::cout << "main: Construct Callback" << std::endl;
Callback callback;
std::cout << "main: Construct Task" << std::endl;
Task task(callback);
std::cout << "main: Connect callback delegate" << std::endl;
boost::shared_ptr<Task> sharedTask = boost::make_shared<Task>(task);
boost::weak_ptr<Task> weakTask(sharedTask);
callback.delegate(weakTask);
callback.delegateSomething();
return 0;
}
如何在 C++ 中的构造函数中为现有对象创建 boost::weak_ptr?
这是我得到的,但它不起作用,因为共享指针构造函数是错误的。问题是我不想做新任务。我想使用创建 TestCallback 所需的任务,但我只想要对 TestTask 的弱引用,因为 TestTask 拥有 TestCallback,如果它消失,那么 TestCallback 也应该消失。
class TestCallback {
public:
TestCallback(TestTask task);
boost::weak_ptr<TestTask> testTask;
};
//构造函数
TestCallback(TestTask task) {
boost::shared_ptr<DeleteStaticRouteTask> sharedTask(task);
boost::weak_ptr<DeleteStaticRouteTask> weakTask(sharedTask);
m_task = weakTask;
}
//理想调用点
TestTask testTask(DependencyA, DependencyB);
TestCallback testCallback(task);
此功能的大部分已包含在 C++ 标准中。如果你不能使用这样的最新版本,那么 boost 库非常接近相同,你可以在此处将 std::
替换为 boost::
。
要从原始指针创建 shared_ptr
或 weak_ptr
,您必须从 enabled_shared_from_this
派生,例如:
class Foo : public std::enabled_shared_from_this<Foo> // C++11
{
};
...
Foo *ptr = ...;
std::shared_ptr<Foo> a = foo->shared_from_this(); // C++11
std::weak_ptr<Foo> b = foo->weak_from_this(); // C++17
enabled_shared_from_this
会为您的类型增加一点尺寸,但是 make_shared
也会对不使用它的类型增加一点尺寸,所以如果这是一个问题,或者通常为了简单起见,有unique_ptr
(C++11) 更像是原始指针。
尝试从堆栈分配的对象中创建一个通常仍然没有意义,因为 shared_ptr 不会像普通局部变量一样阻止它被删除,实际上可能导致双重删除。你可以做一些技巧,比如给它一个 "no-op" 删除器来解决第二个问题。
在 Foo *ptr
的情况下,您还需要确保它的其他一些 shared_ptr
仍然存在,否则 ptr
可能已经被删除了。
所以答案是不能用弱指针实例化一个对象。下面是一个示例,您可以使用它来实现对象之间的弱引用。
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
class Callback;
class Task: public boost::enable_shared_from_this<Task>
{
public:
Task(Callback& callback)
: m_callback(callback)
{
std::cout << "Task:: Constructor" << std::endl;
}
void delegateMethod() {
std::cout << "Task: delegateMethod" << std::endl;
}
private:
Callback& m_callback;
};
class Callback
{
public:
Callback(){
std::cout << "Callback::Constructor" << std::endl;
};
//You have to set the delegate after Construction
void delegate(const boost::weak_ptr<Task> task) {
std::cout << "Callback:: void delegate(const boost::weak_ptr<Task> task) " << std::endl;
this->m_delegate = task;
}
void delegateSomething() {
std::cout << "Callback::delegateSomething()" << std::endl;
boost::shared_ptr<Task> sharedDelegate = this->m_delegate.lock();
std::cout << "sharedDelegate: " << sharedDelegate << std::endl;
if (sharedDelegate) {
// Use *shared_delegate
std::cout << "Callback::delegateSomething() use delegate" << std::endl;
sharedDelegate->delegateMethod();
}
}
private:
boost::weak_ptr<Task> m_delegate;
};
int main()
{
std::cout << "main: Construct Callback" << std::endl;
Callback callback;
std::cout << "main: Construct Task" << std::endl;
Task task(callback);
std::cout << "main: Connect callback delegate" << std::endl;
boost::shared_ptr<Task> sharedTask = boost::make_shared<Task>(task);
boost::weak_ptr<Task> weakTask(sharedTask);
callback.delegate(weakTask);
callback.delegateSomething();
return 0;
}