将字符串作为const char *传递

时间:2016-03-03 03:12:23

标签: c++ string

我可以访问一个类(不是我编写的),它在构造函数中使用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 *缓冲区,并在缓冲区超出范围时删除缓冲区,但这似乎有点重-handed。有更简单/更好的方法吗?

1 个答案:

答案 0 :(得分: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 ) ;

现在它保留了内存和结构。

注意:

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

如果将其传递给函数,例如

callFunction ( *value ) ;

如果他们在您const char*之后放弃value,那么您仍然会有泄漏,而您实际上无法绕过这一点。