2013-01-03 60 views
3

我是C++新手。我假定std::string使用引用计数来确定何时释放缓冲区。在以下示例中,当f()返回时,s缓冲区将被释放。如果我想将字符串缓冲区的所有权授予give_ownership_of而不是释放它?我可以从C++中的std :: string分离缓冲区吗?

void f() 
{ 
    string s = read_str(); 
    give_ownership_of(s); 
} 

UPDATE

让我补充更多的细节到的问题。实际的代码看起来是这样,

string read_str(); 

void write_str_async(const char *str, void (*free_fn)(const char*)); 

void f() { 
    string s = read_str(); 
    // write_str_async() need to access the buffer of s after f() returns. 
    // So I'm responsible to keep s alive until write_str_async() calls free_fn to release the buffer when the write is done. 
    // The PROBLEM here is that s will be released when the variable scope ends. NOTE: I'm not able to change either read_str() or write_str_async() here. 
    write_str_async(s.c_str(), my_free_fn); 
} 
+1

一些实现**在内部使用引用计数机制。它是否引起你的问题? –

+1

你有什么特别的理由想要获得内部'char *'缓冲区的所有权,而不是传递'std :: string'对象吗? – LihO

+0

我不确定这可以做到吗? – james82345

回答

1

有采取std::string的基础数据的所有权是没有标准的方式。通常,应该自己返回一个字符串对象或者让调用者传入一个引用,例如

void f(std::string& s) { 
    s = read_str(); 
} 
4

在C++ 11中,他们添加了类似这样的东西,称为移动。 std::string有一个移动构造函数和一个移动赋值运算符。

这里的编译器可以确定s已达到其寿命结束,因此而不是复制到give_ownership_of它可以移动,它基本上只是复制几个整数/指针周围,而不是std::string的内容。请注意,这比通过引用传递还要慢,所以如果引用对你有用,那么不管你喜欢那个。

https://akrzemi1.wordpress.com/2011/08/11/move-constructor/

我会强烈建议不要使用std::shared_ptr这一点,因为有所有权没有实际的共享。

在情况下,你想移动明确,那么你可以这样做:

give_ownership_of(std::move(s)); 

请注意,您并不需要(事实上也不应该)返回从一个值时使用std::move功能。只需正常返回值。编译器在很多情况下可以执行“返回值优化”,这意味着没有复制和移动。它类似于通过引用传递值并分配给它,除了它实际上给优化器多一点空间(因为它知道std::string是一个不会别名的唯一对象)。阅读也更直接。

0

这个问题不明确,但下面的例子应该说明所有的选择。最后一个可能是你想要的,这是一个新增加的特性,在C++ 11(std::move和右值引用)中。

这允许您将缓冲区传输到同一类型的新对象,但是您永远无法完全消除std::string。您可以忽略该string并将缓冲区内存视为字节,但必须通过销毁string来执行释放。

// will retain s for duration of function 
void give_ownership_of(std::string &s); 

// will retain a copy of s for duration of function 
void give_ownership_of(std::string s); 

struct give_ownership_of { 
    std::string s; 

    // will retain a copy of in_s for object lifetime 
    give_ownership_of(std::string const &in_s) : s(in_s) {} 

    // will transfer buffer of in_s to s and retain that (C++11 only) 
    // you would write give_ownership_of(std::move(s)); 
    give_ownership_of(std::string &&in_s) : s(std::move(in_s)) {} 
}; 
相关问题