C++ shared_ptr<Base> pointer acces violation
我正在使用
我的代码看起来像这样,此外,这实际上类似于我的运行时错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include <iostream> #include <memory> #include <vector> class Base; typedef std::shared_ptr<Base> pBase; class Derived; class Base { public: std::vector<pBase> children; pBase parent; Base() {} virtual ~Base() {} virtual void doSomething() {} void add(pBase i); }; class Derived : public Base { void doSomething() { // Do something... } }; void Base::add(pBase i) { i->parent = pBase(this); children.push_back(i); } int main() { pBase tree = pBase(new Derived()); pBase child(new Derived()); child->add(pBase(new Derived())); tree->add(child); } |
另外,当我在 在 我希望有人能告诉我我做错了什么!但更重要的是,我如何才能解决这个问题!
型
加上其他人的答案:做你想做的事情的规范方法
1 | i->parent = pBase(this); |
是使用
百万千克1
从中派生
1 | class Base : std::enable_shared_from_this<Base> { |
。百万千克1百万千克1
确保每个
1 | pBase child(new Derived()); |
。百万千克1百万千克1
当你想要一个
1 | i->parent = shared_from_this(); |
百万千克1
型
在add()中查看此行
1 | i->parent = pBase(this); |
每次调用add时,都会创建一个指向
尝试(作为开始)使父级成为一个普通的哑指针。
1 | Base *parent; |
。
型
在这里
1 | i->parent = pBase(this); |
您创建了一个智能指针,它从一个普通的旧指针指向一个对象,而不是直接从新指针获得的对象。不要这样做。
正如@roddy所解释的,您可以使用单独的引用计数器来获得单独的智能指针对象。一个指针的两个引用计数器不起作用。
在您的例子中,按照@roddy的建议,将父对象设置为普通指针可能是可以的。这样,您就不会遇到循环引用的问题。只需确保在删除父指针后永远无法访问父指针。如果您将所有子项和父项一起删除(这将自动发生,除非您将更多智能指针存储到它们的其他位置)
如果要初始化智能指针,基本上有两个选择:在每个接口中使用智能指针。不幸的是,这对"this"不起作用,因为它是一个隐式参数。您需要在一个额外的参数中手动将已经创建的智能指针传递给方法。这样地:
1 | tree->add(tree, child); |
号
这有点难看,所以您可能要考虑使"添加"成为静态方法,这样就不需要两次传递父级。
另一种选择是:使用另一种智能指针,如boost::invigative_ptr,您可以在该指针中存储引用计数。这样,您就可以找到引用计数,即使您只有一个类似"this"的愚蠢指针。
编辑:下面@jpalecek的答案更好。用那个。塞巴斯蒂安。