2016-03-03 30 views
0

我有权访问一个类(不是我写的),它将const char*作为构造函数中的参数。如果我有一个字符串,我想传递值作为参数,传递它的安全方式是什么,请记住字符串和类对象可能有不同的作用域?将字符串作为常量字符传递*

我没有访问该类的源代码,所以不要认为它的做法像将字符串复制到类成员中一样健全。

举一个具体的例子,这不起作用:

#include <iostream> 
#include <string> 

class example { 
public: 
    example(const char*); 
    const char* str; 
}; 

example::example(const char* a) : str(a) {} 

int main() { 
    std::string* a=new std::string("a"); 
    example thisDoesntWork(a->c_str()); 
    std::cout << thisDoesntWork.str << std::endl; 
    delete a; 
    std::cout << thisDoesntWork.str << std::endl; //The pointer is now invalid 
    a=new std::string("b"); 
    std::cout << thisDoesntWork.str << std::endl; 
} 

这个工作(只要我可以告诉)更换构造函数,但显然是很可怕:

example thisDoesWorkButIsAwful((new const std::string(*a))->c_str()); //Memory leak! 

同样:

char* buffer=new char[a->size()+1]; 
strcpy(buffer,a->c_str()); //with #include <string.h> added up top 
example(buffer); 

但是,这又容易发生内存泄漏。

我目前的主要想法是制作一个围绕example的包装类,它将字符串复制到char *缓冲区,并在超出范围时删除缓冲区,但看起来有点过分。有更简单/更好的方法吗?

+0

更糟糕的是,它可能会承担指针的所有权,并尝试稍后“释放”它。这是特别有趣的,如果你传递一个字符串文字,虽然我想这样的行为是不是在C API以外的常见:) – melak47

+0

@ melak47我(很漂亮)确定它至少没有这样做。尽管在这一点上我很少会感到惊讶。 ;) – Chris

回答

1

基本上,东西需要坚持内存 - 无论你自己做或自动完成。

一种方法来自动执行:

class SuperThatHoldsIt 
{ 
    std::string mString ; 
    SuperThatHoldsIt (std::string const& str) 
    : mString (str) { } 
} ; 
class HoldingExample 
: private SuperThatHoldsIt 
, public example 
{ 
    holdingExample (std::string const& string) 
    : SuperThatHoldsIt (string) 
    , example (mString.c_str()) 
    { } 
} ; 

std::shared_ptr(或boost::shared_ptr)然后创建它,这将抓住它。

std::string myString ("Hello, world!") ; 
std::shared_ptr<HoldingExample> value = std::make_shared<HoldingExample> (myString) ; 

现在这持有的内存和结构。

注:

原因HoldingExample从两个超类派生是该构造的顺序将工作,因为超类之前局部变量总是初始化。这意味着我们必须在我们自己的成员变量之前构造example,但是我们总是可以初始化一个超类并使用它的成员变量。

如果你通过这个入功能,如

callFunction (*value) ; 

如果他们坚持这种const char*你放开你value后,那么你仍然有泄漏,你真的可以”不要绕过那个。

相关问题