C++ 智能ptr到SEGFULT类的属性
我想知道这个示例是否会导致segfault,因为对象的dtor被称为I,我仍然持有对象属性的共享\u ptrC++ 智能ptr到SEGFULT类的属性,c++,c++11,segmentation-fault,smart-pointers,C++,C++11,Segmentation Fault,Smart Pointers,我想知道这个示例是否会导致segfault,因为对象的dtor被称为I,我仍然持有对象属性的共享\u ptr struct foo{ std::shared_ptr<std::string> const bar = std::make_shared<std::string>("foo"); foo() {std::cout << "CTOR!" << std::endl;} ~foo(){std::cout <&
struct foo{
std::shared_ptr<std::string> const bar = std::make_shared<std::string>("foo");
foo() {std::cout << "CTOR!" << std::endl;}
~foo(){std::cout << "DTOR!" << std::endl;}
};
int main() {
std::shared_ptr<std::string> ptr;
{
std::shared_ptr<foo> foo_ptr = std::make_shared<foo>();
ptr = foo_ptr->bar;
}
std::cout << *ptr << std::endl;
return 0;
}
structfoo{
std::shared_ptr const bar=std::make_shared(“foo”);
foo(){std::cout不,它不会。通过将std::shared_ptr分配给另一个,你就是在拒绝它死亡
此操作ptr=foo\u ptr->bar;
将使共享指针的计数器增加一个。这将保证空闲存储上动态分配的对象仍然有效
即使是被摧毁对象的属性也是如此吗?!
是的,这是真的。在非正式的谈话中,动态分配内存的一个用途是当你希望你的对象比它的所有者(另一个对象,指针…)活得更多时。因此,在容器对象死后,该对象将活得更好
尝试执行此代码。它会让您明白:
std::shared_ptr<std::string> ptr;
{
std::shared_ptr<foo> foo_ptr = std::make_shared<foo>();
std::cout <<"References Count:" << foo_ptr->bar.use_count()<<"\n";
ptr = foo_ptr->bar;
std::cout <<"References Count:" << foo_ptr->bar.use_count()<<"\n";
}
std::cout <<"References Count:" << ptr.use_count()<<"\n";
std::cout << *ptr << std::endl;
这里没有问题。std::shared\u ptr
就是为了做到这一点而设计的。如果我们看看代码是如何工作的,你会发现这一点
std::shared_ptr<std::string> ptr;
现在,我们创建名为foo\u ptr
的shared\u ptr
,它指向foo
的一个有效实例,并且foo
的构造函数初始化bar
。然后我们将bar
分配给ptr
。当我们这样做时,bar
的内部引用计数器增加一(到二)现在bar
和ptr
共享内部指针。然后我们到达作用域的末尾,foo\u ptr
被销毁,当它被销毁时,它调用foo
的析构函数,该析构函数调用bar
的析构函数。当bar
被销毁时,它放弃对指针的访问。这意味着它递减参考计数器。如果它是最后一个共享的\u ptr
(输入析构函数时计数器为1),则指针也会被删除,如果不是,则它不会执行任何其他操作。因为计数器不止一个(由于ptr=foo\u ptr->bar
,所以计数器为2)指针不会被删除,但会保留在ptr
中,因为所有权是共享的
std::cout那么该对象将被销毁,但该属性仍处于活动状态?刚才我认为它是指向该对象的指针,而不是指向其属性..我不确定让我check@Exagon,是的。没错。这就是共享ptr的目的。是的,它仍然是一个活的,我会编辑来解释more@Exagon:需要澄清的是:属性ba在foo\u ptr
超出范围后,r
将不会处于活动状态,但ptr
不会指向bar
。相反,它指向bar
指向的任何对象,并且该对象保证仍然处于活动状态。使用共享指针管理foo
对象只是噪音,与您的内核无关例如,您可以将其创建为堆栈上的本地对象。
std::shared_ptr<std::string> ptr;
{
std::shared_ptr<foo> foo_ptr = std::make_shared<foo>();
ptr = foo_ptr->bar;
}
std::cout << *ptr << std::endl;