复制const char *

时间:2010-02-18 10:10:20

标签: c++ string char

我从一个函数接收一个c-string作为参数,但我收到的参数将在以后销毁。所以我想复制一份。

这就是我的意思:

class MyClass
{
private:
 const char *filename;

public:
 void func (const char *_filename);
}

void MyClass::func (const char *_filename)
{
 filename = _filename; //This isn't going to work
}

我想要实现的不是简单地将一个内存地址分配给另一个,而是复制内容。我希望文件名为“const char *”而不是“char *”。

我尝试使用strcpy,但它要求目标字符串为非const。

有办法解决吗?没有在文件名上使用const_cast的东西?

感谢。

8 个答案:

答案 0 :(得分:25)

使用std::string复制值,因为您已经在使用C ++。如果您需要const char*,请使用c_str()

class MyClass
{
private:
    std::string filename;
public:
    void setFilename(const char *source)
    {
        filename = std::string(source);
    }

    const char *getRawFileName() const
    {
        return filename.c_str();
    }
}

答案 1 :(得分:7)

我同意最好的事情(至少在不了解你的问题的情况下)是使用std::string。但如果你坚持自己管理内存,你必须完全管理它。所以C ++方式:

class MyClass
{
private:
 const char *filename;

 MyClass(const MyClass&); // no implementation
 MyClass operator=(const MyClass &); // no implementation

public:
 MyClass() {filename = 0;}
 ~MyClass() {delete[] filename;}

 void func (const char *_filename);
}

void MyClass::func (const char *_filename)
{
 const size_t len = strlen(_filename);
 char * tmp_filename = new char[len + 1];
 strncpy(tmp_filename, _filename, len);
 tmp_filename[len] = '\0'; // I'm paranoid, maybe someone has changed something in _filename :-)
 delete[] filename;
 filename = tmp_filename;
}

和C方式

class MyClass
{
private:
 const char *filename;

 MyClass(const MyClass&); // no implementation
 MyClass operator=(const MyClass &); // no implementation

public:
 MyClass() {filename = 0;}
 ~MyClass() {free(filename);}

 void func (const char *_filename);
}

void MyClass::func (const char *_filename)
{
 free(filename);
 filename = strdup(_filename); // easier than C++, isn't it?
}

答案 2 :(得分:2)

您必须决定是否要将文件名设为const(因此无法更改)或非const(因此可以在MyClass :: func中更改)。

答案 3 :(得分:1)

[假设您继续以C风格实现您的类'内部,这在开发和执行速度方面可能有利或可能没有好处(取决于整个项目的设计),但通常不建议使用 std::string 和朋友们。]

车削

const char *filename;

char *filename;

不会让你对strcpy感到满意,因为你实际上需要一些内存来复制你的字符串:)

对于手动内存管理代码部分,请参阅Tadeusz Kopec的答案,它似乎没有问题。

另外,请记住

之间存在差异
const char *filename; // "filename" points to "const char" 
                      //  and is not const itself
char const *filename; // semantically the same as above

char * const filename; // "filename" is const and points to "char", 
                       //  which is not const

在第一种情况下,您可以将filename指向任何其他const char字符串,在第二种情况下,您只能“就地”更改该字符串(因此保留{{1}值相同,因为它指向相同的内存位置)。当然,如果需要,可以将这两者(或者没有一部分)结合起来。

P.S。如果您为成员函数的参数filename命名只是为了避免命名与成员变量_filename的冲突,您可以在其前面添加filename(并删除下划线):

this

答案 4 :(得分:1)

标准C库中有一个函数(如果你想进入C路由),名为_strdup。它使用malloc进行实际分配,因此当你完成字符串时你需要自由调用。

例如,

void MyClass::func (const char *_filename)
{
    if (filename)
    {
        free(filename);
    }
    filename = _strdup(_filename);
}

当然,不要忘记在析构函数中释放文件名。

答案 5 :(得分:0)

如果你想坚持使用普通的C,请使用strncpy。但我同意Ilya,使用std :: string,因为它已经是C ++了。如果你的应用程序正在调用你的方法,你甚至可以首先收到一个std :: string,因为原始参数将被销毁。

答案 6 :(得分:0)

为什么你把它作为const,如果你需要在类的一个方法中改变它们。

无论如何,非静态const数据成员和引用数据成员不能被赋值;你应该使用初始化列表和构造函数来初始化它们。

MyClass::MyClass(const char *_filename) : filename( _filename ) 
{ 
   // filename = _filename; This isn't going to work 
}

初始化程序也可以调用以下函数

MyClass::MyClass(const char *_filename) : filename( getfilename() ) 
{ 
   // filename = _filename; This isn't going to work 
}

没有验证这个特定情况是否恰当,但初始化列表是为非静态const数据成员赋值的方法。

答案 7 :(得分:-1)

char const*表示该类不拥有与之关联的内存。所有者总是需要一个非const指针,否则无法释放内存。如果有非const指针,则可以为其分配内存,然后使用strcpy(或memcpy)复制字符串本身。但是,在您使用std::string的情况下,这是一个更好的选择。