【问题标题】:how to defer delete operation of shared_ptr?如何推迟shared_ptr的删除操作?
【发布时间】:2015-05-25 06:59:46
【问题描述】:

我在 main 中创建了一个 sample 类的指针。我将此指针传递给函数function1()。这个函数必须使用指针作为共享指针,并使用这个指针做一些操作。在function1() 退出期间,sample 的析构函数因shared_ptr 而被调用。当我将相同的指针传递给不同的函数时,该指针不再有效并且程序崩溃。

1.如何推迟function1()中的删除操作(销毁调用)?

2.什么是替代方法,以便我可以将指针传递给不同的函数并安全地使用它,尽管有些函数使用指针作为shared_ptr?

这里有示例代码和输出。

#include <memory>
#include <iostream>
#include <string.h>

using namespace std;

class sample
{
    private:
        char * data;

    public:
        sample( char * data )
        { 
            cout << __FUNCTION__ << endl;
            this->data = new char[strlen( data)];
            strcpy( this->data, data ); 

        }
        ~sample()
        {
            cout << __FUNCTION__ << endl; 
            delete this->data; 
        }
        void print_data()
        { 
            cout << __FUNCTION__ << endl;
            cout << "data = " << this->data << endl;
        }
};

void function1( sample * ptr )
{
    shared_ptr<sample> samp( ptr );
    /* do something with samp */
    ptr->print_data();
}

void function2( sample * ptr )
{
    ptr->print_data();
}

int main()
{
    char data[10] = "123456789";
    data[10] = '\0';
    sample * s = new sample( data );

    function1( s );
    function2( s );

    return 0;
}

输出:

sample
print_data
data = 123456789
~sample
print_data
data = 

【问题讨论】:

  • 您在 sample 构造函数中有一个错误。你忘记了 C 风格的字符串有一个额外的终止字符。对字符串使用std::string
  • 当您执行data[10] = '\0'; 时,您有一个错误。由于你用字符串初始化数组,而且数组足够大,它已经被终止了,不需要再添加一个终止符。同样,在 C++ 中使用 std::string 处理字符串。
  • 为什么 function1 需要 shared_ptr ?它是否拥有样本的所有权?
  • 不应该这样做。您编写的代码以一种根本错误的方式使用智能指针;您应该努力重写代码,以便它以预期的方式使用智能指针,而不是尝试修改代码以使其按原样工作。

标签: c++ pointers shared-ptr smart-pointers


【解决方案1】:

改变

sample * s = new sample( data );

进入

shared_ptr<sample> s(new sample( data ));

并将共享指针传递给所有函数。当此变量超出范围时,它将被删除,对于您的目的来说已经足够晚了

【讨论】:

  • 更好用std::make_shared&lt;sample&gt;(data)
  • 由于function2 不需要共享指针,最好用function2(s.get()); 调用它
【解决方案2】:

不应该这样做。如果您想共享指针的所有权,则应该将其创建shared_ptr,并作为shared_ptr 传递给也希望共享所有权的函数。

也就是说,如果您真的知道自己在做什么,并且您必须破解一些东西来完成这项工作,您可以使用自定义删除器什么都没有:

struct null_deleter {
    // Generic so it will work with any type!
    template< typename T >
    void operator()(T *p) const {}
};

void function1( sample * ptr )
{
    shared_ptr<sample> samp( ptr, null_deleter() );

    // I really hope this function isn't expecting
    // me to actually share ownership with it....
    something(samp); 

    ptr->print_data();
}

【讨论】:

    猜你喜欢
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多