首先,我想介绍一下我的情况:
我已经编写了一些将char *指针作为私有类成员的类。此项目也有GUI,因此当单击按钮时,某些函数可能会执行多次。这些类设计为单个类在project.But它们的一些函数可以执行多次。然后我发现我的项目有内存泄漏。
所以我想问下列问题:
例如:
class A:
{
public :
setStr(char * s){//need new or just use =?};
A & operator=(const A& other){//also need new?};
manyTimesFunctions(char * other)
{
//need to use chars other to assignment str
//how to carefully use new to avoid memory leak?
//other may be another class's locality none const variable
}
private:
char * str;
}
因此,该项目只启动A类一次,但可能多次使用setStr
和manyTimesFunctions
。
我想我已经找到了我需要照顾的事项:copy that class,答案对我来说真的很有用。
答案 0 :(得分:2)
只需使用std::string
即可。它为您负责内存管理。然后成员声明看起来像
std::string str;
并且setter函数看起来像
void setStr( char const* s ) { str = s; }
如果您想使用字符串并需要char const*
,请写下str.c_str()
。
使用标准库类型(如std::string
)并且没有手动动态分配,通常不需要关注operator=
:编译器生成的副本分配可以很好地工作。
顺便说一下,为成员变量决定一些命名约定通常是一个好主意。 C ++的常见内容包括str_
,mStr
和my_str
。下划线后缀可能是最常见的后缀,但不要使用像_str
这样的前导下划线,因为虽然技术上允许它与实现定义名称的约定冲突(例如,全局中的标识符不允许使用前导下划线)命名空间)。
答案 1 :(得分:1)
我不是100%确定你要做什么。但是,由于char *是一个指针,您可以简单地传递引用。
char* operator=(char* s) { str = s; }
只要知道,如果你修改了函数中的值,它就会修改你从
复制它的地方如果char *实际上需要克隆,那么它不会修改原始值。首先需要获取char *的长度。
这可以通过此功能
完成unsigned Length(char* s)
{
unsigned I = 0;
while( *(s+I) != '\0')
I++;
return I;
}
可以按如下方式创建新字符串
str = new char[LENGTH];
此时,您可以按术语
复制字符串for(I = 0 ; I < LENGTH; I++)
{
str[I] = s[I];
}
最后为了避免内存泄漏,需要在类析构函数
中删除它~A()
{
delete [] str;
}
当然使用std :: string可以节省很多问题。
答案 2 :(得分:0)
此答案将用于对比给出使用状态std::string
的其他答案(并且这些答案是正确的 - 使用std::string
)。
假设您只能使用char *
,由于某种原因您无法使用std::string
,并且您正在处理以NULL结尾的字符串。这是您的实施必须执行的操作的概要(请将其与仅使用std::string
进行比较):
#include <algorithm>
#include <cstring>
class A
{
public:
// construct empty string
A () : str(new char[1]()) {}
// construct from non-empty
A(const char *s) : str(new char[strlen(s) + 1])
{ strcpy(str, s); }
// copy construct
A(const A& rhs) : str(new char[strlen(rhs.str) + 1])
{ strcpy(str, rhs.str); }
// destruct
~A() { delete [] str; }
// assign
A& operator=(const A& rhs)
{
A temp(rhs);
std::swap(str, temp.str);
return *this;
}
// setter
void setStr(char * s)
{
A temp(s);
*this = temp;
}
// getter
const char* getStr() { return str; }
private:
char * str;
};
在添加了几个构造函数和一个getter函数之后,这将遵循Rule of 3。
您看到我们需要添加多少代码才能使类安全地可复制和分配?这就是为什么使用std::string
比使用char *
更方便。对于std::string
,与添加复制/分配(以及移动,我没有显示)功能相比,需要更改一行。
底线是在C ++中,如果你想要字符串,请使用字符串(std::string
)并尽量避免使用char *
(除非你有一个非常令人信服的理由使用{{1}表示字符串数据)。