我想知道关于参数传递nullptr的C ++ 11最佳实践。我想通过将nullptr传递给已存在的setter函数来重置类成员对象。举个简单的例子:
#include "foo.h"
Foo my_foo;
void set_foo(std::shared_ptr<Foo> bar){
my_foo = bar;
}
int main()
{
set_foo(std::make_shared<Foo>());
//do stuff
set_foo(nullptr);
}
这可以吗?或者,还是有更好的,更优选的方法来重置my_foo?我不想再用另一种方法来重置my_foo。
我正在处理的应用程序的真正动机是我有一个持久的单例类,由可变数量的其他类共享。对于那些其他类的编码目的来说,只需在它们需要的时间内拥有一个指向该单例的共享指针并使用它,然后在不再允许它们访问它时放弃/设置为nullptr。如果有什么我可能会遗漏或没有想到,任何建议都非常感谢,谢谢!
答案 0 :(得分:0)
虽然有许多不同的范例可以与C ++一起使用,但您可以使用方法将数据和操作捆绑在一起吗?
但是你可能不想更改Foo
界面,所以我猜你想要实现像 Singleton模式这样的东西,还有一个用于销毁它的附加功能吗? / p>
在这种情况下,我更喜欢两种不同的功能。当你有两个不同名称的函数时,它是“使界面易于正确使用且难以正确使用”的更好方法(原文如请参阅Scott Meyers)。如果你在一个不适合它的名字的函数中隐藏一个功能,那就意味着它“很难”。
这将转化为
#include "foo.h"
Foo my_foo;
void set_foo(std::shared_ptr<Foo> bar){
my_foo = bar;
}
void clear_foo(){
my_foo = nullptr;
}
int main()
{
Foo foo.set(std::make_shared<Foo>());
//do stuff
clear_foo();
}
...虽然我不太清楚将shared_ptr<Foo>
分配给Foo
operator
set_foo
的{{1}}是什么意思,我只是在这里使用了您的代码。< / p>
使用可以处理设置和清晰功能的包装器我会更舒服。 从这里开始,我甚至会走到目前为止并使用资源获取初始化(RAII),你可以在这里介绍一下(仅限草图):
#include "foo.h"
struct FooWrapper {
shared_ptr<Foo> bar_;
FooWrapper() : bar_(nullptr) {}
FooWrapper(shared_ptr<Foo> bar) : bar_(bar) {}
void set(shared_ptr bar<Foo> bar) { bar_ = bar; }
void clear() { bar = nullptr; }
Foo* operator->() { return bar_.get(); }
};
FooWrapper my_foo{};
int main()
{
my_foo.set(std::make_shared<Foo>()); // 1
my_foo->do_stuff();
my_foo.clear(); // clear
my_foo.set(std::make_shared<Foo>()); // 2
} // forgot to clear, doesn't matter FooWrapper takes care of that.
我想你可以免除整个FooWrapper
,只需使用全局shared_ptr<Foo> foo
。
#include "foo.h"
shared_ptr<Foo> my_foo{nullptr};
int main()
{
my_foo.reset( new Foo{} ); // 1
my_foo->do_stuff();
my_foo.reset( new Foo{} ); // 2
my_foo.reset(nullptr); // clear
}
如您所见,shared_ptr
使用模式将两种不同的功能捆绑到reset
- 方法中。所以,它完全不好。