- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我知道由 std::shared_ptr
管理的对象不是 delete
d by reset()
除非它是唯一的 shared_ptr
在那个时候管理它。我知道当有多个 shared_ptr
s managing the same object, managed object's value changes are reflected through shared_ptr
就是指向它,同时更改其中任何一项 shared_ptr
的值(不是其托管对象的值)由 reset()
引起调整它(即将 shared_ptr
从指向原始托管对象的一个更改为指向任何内容或其他内容的一个)不会更改另一个 shared_ptr
s的值(即都指向原来的托管对象,原来的托管对象仍然存在):
#include <memory>
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<shared_ptr<int>> vec{ make_shared<int>(5) };
shared_ptr<int> sptr(vec[0]);
++ *sptr;
cout << *vec[0] << endl; // 6
vec[0].reset();
vec.pop_back();
cout << *sptr << endl; // 6
}
但是当使用两个间接级别时,我就失去了这种逻辑。给定一个名为 Wrapper
的类和一个 shared_ptr<shared_ptr<Wrapper>>
和任意数量的其他 shared_ptr<shared_ptr<Wrapper>>
s初始化为之前的,为什么这个配置允许一个reset()
调用任何内部 shared_ptr
有效reset()
所有其他内部 shared_ptr
是吗?
我的猜测是:任何outer shared_ptr
的托管对象s 是内部 shared_ptr
(不是 Wrapper
)并更改内部 shared_ptr
的值(通过 reset()
调整内部 shared_ptr
,这将内部 shared_ptr
的值从指向 Wrapper
实例的值更改为指向任何内容的实例)反射(reflect)在所有 out呃shared_ptr
s,有效地导致所有 outer shared_ptr
s 失去对 Wrapper
的间接管理实例,从而删除 Wrapper
实例。
但按照同样的逻辑,重置内部指针之一不会导致该特定内部指针失去对 Wrapper
的管理权吗? ?鉴于所有其他外部指针都指向它们自己的内部指针(即用它们构造的内部指针),那些外部指针不会继续对 Wrapper
进行间接管理吗? ,因为重置一个内部指针不会改变 Wrapper
的值,其他内部指针应该仍然可以访问它吗?这对我来说是个悖论。
如果重置一个内部指针会有效地重置所有内部指针,那么这意味着内部指针的 use_count()
是1
就在 reset()
之前.我想到的唯一方法是多个shared_ptr
s 可以出现 来管理同一个对象,同时保持 use_count()
在 1
将是通过幻觉:他们管理具有相同值的不同对象(即不同地址的对象)。我通过制作 int
来测试这个包装器名为 Wrapper
,其唯一的数据成员是包装的 int
和一个 static
instance_count
跟踪 Wrapper
的数量当前存在的实例。
struct Wrapper {
Wrapper(int par = 0) : num(par) { ++instance_count; }
Wrapper(const Wrapper& src) : num(src.num) { ++instance_count; }
~Wrapper() { --instance_count; }
int num;
static int instance_count;
};
int Wrapper::instance_count = 0;
int main() {
shared_ptr<shared_ptr<Wrapper>> dual_ptr_1(
make_shared<shared_ptr<Wrapper>>(
make_shared<Wrapper>(Wrapper(5))
)
);
// - Output -
cout << Wrapper::instance_count << endl; // 1
shared_ptr<shared_ptr<Wrapper>> dual_ptr_2(dual_ptr_1);
cout << Wrapper::instance_count << endl; // 1
cout << dual_ptr_1->use_count() << endl; // 1
cout << dual_ptr_2->use_count() << endl; // 1
cout << dual_ptr_1.use_count() << endl; // 2
cout << dual_ptr_2.use_count() << endl; // 2
// note that above, the '->' operator accesses
// inner ptr while '.' operator is for outer ptr
cout << (*dual_ptr_1)->num << endl; // 5
cout << (*dual_ptr_2)->num << endl; // 5
dual_ptr_2->reset();
cout << Wrapper::instance_count << endl; // 0
cout << dual_ptr_1->use_count() << endl; // 0
cout << dual_ptr_2->use_count() << endl; // 0
cout << dual_ptr_1.use_count() << endl; // 2
cout << dual_ptr_2.use_count() << endl; // 2
}
显然有 2
指向 1
的内部指针Wrapper
目的;内部指针的 use_count
最多是1
(销毁前); Wrapper
类(class)的instance_count
最多是1
(销毁前);和间接管理的Wrapper
对象可以通过两个外部指针访问(这意味着两个外部指针都没有被另一个移动构造);并重置一个内部指针有效地重置了所有这些指针;所以我还是不明白这个看似矛盾的现象。
我也在这篇文章中就上述代码具有内部 shared_ptr
的情况提出了同样的问题。 s 替换为 unique_ptr
s,内部make_shared
替换为 make_unique
, 和 use_count()
注释掉内部指针(因为 unique_ptr
缺少该方法),它提供相同的输出。这对我来说似乎是个悖论,因为 unique_ptr
s 在这里似乎并不独特。
最佳答案
Given a class named
Wrapper
and ashared_ptr<shared_ptr<Wrapper>>
and any number of othershared_ptr<shared_ptr<Wrapper>>
s initialized to the prior, why does this configuration allow areset()
called on any inner shared_ptr to effectivelyreset()
all other innershared_ptrs
?
没有其他内在shared_ptr
s,你有一个包含对象的实例,即
dual_ptr_1
\
--> shared_ptr --> Wrapper
/
dual_ptr_2
而不是
dual_ptr_1 --> shared_ptr
\
--> Wrapper
/
dual_ptr_2 --> shared_ptr
在您调用 dual_ptr_2->reset();
之后这改变为
dual_ptr_1
\
--> shared_ptr --> (empty)
/
dual_ptr_2
关于c++ - 将 shared_ptr 的嵌套智能指针重置为 shared_ptr(或 unique_ptr),看似矛盾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26748634/
我进行了搜索以查看是否找到了解决此问题的方法,但没有找到答案。我遇到的问题是在我的代码编译时,我没有得到 intellisense 如果我收到一个参数(或声明一个变量),例如使用模板 T : uniq
我想在多态情况下将派生类 unique_ptr 的所有权转移到它的抽象基类 unique_ptr。怎么走? class Fruit { public: virtual void print()
unique_ptr> 之间有什么区别?和一个 list> ?威尔list>导致元素的内存也被自动管理? 最佳答案 说unique_ptr<>就像在说 *但具有自动删除的额外好处。 unique_pt
我第一次在我的项目中使用智能指针。在使用 unique_ptr 时,我对 unique_ptr 和原始指针组合有一些疑问。以及 unique_ptr 内部工作的方式。 有人可以根据我的理解解释/回答如
我创建了一个派生自 std::istream 的自定义 istream,当文件是压缩文件时使用自定义 streambuf,否则使用 std::filebuf。 #mystream.h class my
目前我正在尝试使用 std::unique_ptr,但我在 Visual Studio 2012 中遇到编译器错误。 class A { private: unique_ptr other; pub
我有以下三个代码片段来演示一个容易重现的问题。 using namespace boost::filesystem; using namespace std; int main() { pat
这个问题令人困惑,所以这里是我正在尝试做的事情的精简版: #include #include class A { }; class B : public A { public:
假设 class Owner 有 Member 成员,它还必须有一个指向它的 const 所有者的 const 指针。该指针在 Owner 的构造函数中提供给 member,该构造函数接受指向构成 m
下面的代码会抛出一个警告: 警告 C4239:使用了非标准扩展:“参数”:从“std::unique_ptr”到“std::unique_ptr &”的转换 std::unique_ptr foo()
这个问题在这里已经有了答案: Returning unique_ptr from functions (7 个答案) 关闭 8 年前。 我是 unique_ptr 的新手。一切都很顺利,直到我遇到一
如果 vector 不是 unique_ptr 或者如果我没有 vector 的 unique_ptr(并且不取消引用)它可以工作,但两者都会导致编译错误。我不确定发生了什么。 auto v = st
我正在尝试使用 unique_ptr到接受 unique_ptr 的函数中的派生类到基类。比如: class Base {}; class Derived : public Base {}; void
我是 C++ 和智能指针的新手,尤其是 unique_ptr 的行为。下面是我正在试验的一段代码: unique_ptr u1 = make_unique(2); unique_ptr u2 =
我类有这个成员: static std::unique_ptr[]> changestatecommands; 而且我找不到正确的方法来初始化它。我希望数组被初始化,但元素未初始化,所以我可以随时编写
我编写了以下使用 unique_ptr 的代码其中 unique_ptr预计 class Base { int i; public: Base( int i ) : i(i) {}
我有一个非常具体的需求,需要访问特定于派生类的功能,我在构建包含类时在 unique_ptr 中获得了该派生类的实例。然后,该包含类必须将其基类的 unique_ptr 上转型移动到包含类的基类构造函
有人可以建议如何使用自定义删除器从模板化唯一指针池返回唯一指针。 在下面的代码片段中,我使用 ObjectPool.h 作为我的模板类来获取一堆唯一指针。我正在使用 ObjectPool 在 DBCo
我在 std::vector> 中维护了一些对象池我将这个池中的对象传递给一个函数 void process(...) .我不清楚将这些对象之一传递给 process() 的最佳方式功能。如果我理解我
我用一个对象初始化了一个unique_ptr。因为我想将它的引用传递给函数并且不让函数更改对象内容,所以我必须传递 unique_ptr&给它。但是 gcc 5.4 不允许我初始化 unique_pt
我是一名优秀的程序员,十分优秀!