【发布时间】:2019-11-19 03:26:45
【问题描述】:
我有一个类,其对象指针将作为键/数据添加到多个 std::map/std::unordered_map/hash(内部实现)中。为了自动删除我正在使用 shared_ptr 的对象。
我使用shared_ptr only 类设计了我的课程。
现在我想确保将来没有人这样做:
#include <memory>
#include <string>
class A {
protected:
struct this_is_private;
public:
explicit A(const this_is_private &) {}
A(const this_is_private &, ::std::string, int) {}
template <typename... T>
static ::std::shared_ptr<A> create(T &&...args) {
return ::std::make_shared<A>(this_is_private{0},
::std::forward<T>(args)...);
}
protected:
struct this_is_private {
explicit this_is_private(int) {}
};
A(const A &) = delete;
const A &operator =(const A &) = delete;
};
::std::map<A*, int> m_error;
::std::map<::std::shared_ptr<A>, int> m_ok;
::std::shared_ptr<A> foo()
{
::std::shared_ptr<A> temp = A::create();
A * obj_ptr = temp.get();
m_error.insert(pair<A*, int>(obj_ptr, 10)); //How to make sure no one do this in future
m_ok.insert(pair<::std::shared_ptr<A>, int>(temp,10)); //ok
}
【问题讨论】:
-
人们总是能够创建指向现有对象的原始指针。如果不使用
create函数,您已经无法创建A。如果有人真的想朝自己的脚开枪,你无法阻止他们。 -
就像 super 所说的那样,你无法阻止人们朝自己的脚开枪。不过,您可以做的一件事是拥有良好的代码审查流程,并要求在创建指针时使用
make_unique和make_shared。 -
您可以编写一个包装类来包装内部存储的
shared_ptr<A>。但最终人们也可以获取/存储 that 的指针。更不用说您可以轻松地存储对A的引用(只需取消对shared_ptr<A>的引用),这更不可能避免。 -
为了澄清你的问题:更一般地说,你想防止人们获得指向你的 A 类对象的原始指针吗?
-
您可以为您的班级
delete和operator&以防止任何人以简单的方式获取其地址,但也有std::addressof,当然还有std::shared_ptr<A>::get(以及其他10 个方式),你不可能阻止。 godbolt.org/z/vDw801
标签: c++ c++11 memory-management stl smart-pointers