简体   繁体   English

如何在C ++中保留局部变量的值并在外部重新访问

[英]How to retain local variable's value and revisit outside in C++

I use boost shared_ptr to wrap a pointer. 我用boost shared_ptr包装一个指针。 However I can only get the correct value in test_shared_ptr(), while in main(), I get the wrong value. 但是,我只能在test_shared_ptr()中获得正确的值,而在main()中,我得到错误的值。

Expected output: 预期产量:
100 100
100 100

Actual output: 实际输出:
100 100
-572662307 -572662307

It seems that the pointer becomes invalid in that case. 在这种情况下,指针似乎变得无效。 Any correct approach to do the job? 任何正确的方法来完成这项工作? Thanks in advance. 提前致谢。

Below is the source code. 下面是源代码。

#include <memory>
#include <iostream>


class TestClass
{
public:
    TestClass(int &i);
    void print_i();
private:
    int *_i;
};

TestClass::TestClass(int &i) : _i(&i)
{

}

void TestClass::print_i()
{
    std::cout << *_i << std::endl;
}


void print_i(int &i)
{
    std::cout << i << std::endl;
}

TestClass *test_shared_ptr()
{
    std::tr1::shared_ptr<int> i(new int());

    *i = 100;

    print_i(*i); 

    return new TestClass(*i);
}


int main(int argc, char** argv)
{
    TestClass *p = test_shared_ptr();
    p->print_i();
    return 0;
}

You need to pass around the shared pointer, rather than references and pointers directly to the int. 您需要传递共享指针,而不是直接将引用和指针传递给int。

What's happening is the shared pointer is never passed anywhere outside the test_shared_ptr() function. 发生的事情是共享指针永远不会传递到test_shared_ptr()函数之外的任何地方。 When that function returns, the shared pointer is destroyed. 当该函数返回时,共享指针将被销毁。 When it sees that nothing else has a reference to it's memory, it destroys the memory it was pointing at. 当发现没有其他引用对其内存的引用时,它将破坏其指向的内存。

Basically, where you are using int &i and int *i change both to use std::tr1::shared_ptr<int> i . 基本上,在使用int &iint *i将它们都更改为使用std::tr1::shared_ptr<int> i

You probably need to read up on shared pointer a bit more. 您可能需要多读一些共享指针。 Basically, they keep a reference count for the pointer they are pointing to. 基本上,它们为所指向的指针保留引用计数。 When they are copied, they up the reference count, and when they are destroyed the decrement it. 复制它们时,它们将增加引用计数,销毁它们时将其递减。 When the reference count reaches 0 (nothing else is referencing the memory it is pointing at) it frees that memory. 当引用计数达到0(没有其他东西正在引用它所指向的内存)时,它将释放该内存。 So, even though something is using that pointer in your case, because it did not use a shared pointer there is no way for the shared pointer to know that the memory is still being used, so it frees it. 因此,即使在您的情况下某些东西正在使用该指针,因为它没有使用共享指针,所以共享指针无法知道内存仍在使用中,因此它将释放它。

It seems that the pointer becomes invalid in that case 在这种情况下,指针似乎变得无效

Of course it becomes invalid. 当然,它变得无效。 shared_ptr gets deleted when you leave test_shared_ptr, and i does not exist after that. 当您离开test_shared_ptr时,shared_ptr会被删除,此后我不存在。

Any correct approach to do the job? 任何正确的方法来完成这项工作?

1) simply copy value of i. 1)简单地复制i的值。 (use int i instead of int* i in TestClass). (在TestClass中使用int i而不是int * i)。 int is small, you won't lose anything. int很小,您不会丢失任何东西。

or 要么

2) use std::tr1::shared_ptr<int> instead of int* in TestClass. 2)在测试类中使用std :: tr1 :: shared_ptr <int>代替int *。

The issue you are having is with your API contract. 您遇到的问题与API合同有关。

I don't want to use shared pointer to pass variable values in TestClass's constructor, since I don't want to force the api user to use smart pointer 我不想使用共享指针在TestClass的构造函数中传递变量值,因为我不想强制api用户使用智能指针

Your TestClass contract is currently looking like you want the caller to maintain the int item so that it has a lifetime longer than TestClass . 当前,您的TestClass合同看起来像您希望调用方维护int项,以便其寿命比TestClass更长。

Your test case doesn't follow this contract rule however. 但是,您的测试用例不遵循此合同规则。

Actually I want to pass object by reference instead of generic type in my application. 实际上,我想在我的应用程序中通过引用而不是通用类型传递对象。

Passing by reference or by pointer does not have anything to do with 'generic' type. 通过引用或指针传递与“泛型”类型无关。

Here is a possible fix for your code testing your API, the scope of your int is then longer then sufficiently long (untill the end of the app) to handle all usages within TestClass 这是您的代码测试API的一种可能的修复方法,然后int的范围就长了,然后又足够长(直到应用程序结束)以处理TestClass所有用法

TestClass *test_shared_ptr(int &i)
{
    i = 100;

    print_i(i); 

    return new TestClass(i);
}


int main(int argc, char** argv)
{
    std::tr1::shared_ptr<int> i(new int());

    TestClass *p = test_shared_ptr(*i);
    p->print_i();
    return 0;
}

What you are doing really breaks the point of shared_ptr. 您所做的确实打破了shared_ptr的意义。 Basically when you pass it out of that function is it magically supposed to break and, thus, not free the pointed too memory? 基本上,当您将其从该函数中传递出去时,它是否应该神奇地打破了,因此不能释放指向的内存呢?

No. It frees it. 不,它可以释放它。 Are you expecting the shared_ptr to still exist outside of the function so that when "p" drops out of scope it manages to call teh shared_ptr destructor? 您是否希望shared_ptr仍然存在于函数之外,以便当“ p”超出范围时,它将设法调用shared_ptr析构函数? This can't happen. 这不可能发生。 p is a pointer not a shared_ptr class. p是一个指针,而不是shared_ptr类。

Either return a shared_ptr or return the new'd pointer and delete it yourself. 返回shared_ptr或返回new'd指针并自己删除它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM