如何防止复制传递给avr-gcc C ++构造函数的字符串?
题
在 ArduinoUnit 单元测试库中,我提供了一种为TestSuite命名的机制。库的用户可以编写以下内容:
TestSuite suite("my test suite");
// ...
suite.run(); // Suite name is used here
这是预期的用法 - TestSuite的名称是字符串文字。然而,为了防止难以发现的错误,我觉得有必要迎合不同的用法,例如:
char* name = (char*) malloc(14);
strcpy(name, "my test suite");
TestSuite suite(name);
free(name);
// ...
suite.run(); // Suite name is used here
因此我已经实现了这样的TestSuite:
class TestSuite {
public:
TestSuite(const char* name) {
name_ = (char*) malloc(strlen(name) + 1);
strcpy(name_, name);
}
~TestSuite() {
free(name_);
}
private:
char* name_;
};
抛开构造函数中未能处理内存分配失败的问题,我宁愿简单地将指针分配给成员变量,如下所示:
class TestSuite {
public:
TestSuite(const char* name) : name_(name) {
}
private:
const char* name_;
};
有什么办法可以改变界面以强制它'正确'使用,这样我就可以取消动态内存分配了吗?
解决方案
如果你提供两个重载的构造函数怎么办?
TestSuite(const char* name) ...
TestSuite(char* name) ...
如果使用const char*
调用,则构造函数可以复制指针,假设该字符串不会消失。如果使用char*
调用,构造函数可以复制整个字符串。
请注意,当name
实际上是动态分配时,仍然可以通过将<=>传递给构造函数来破坏此机制。但是,这可能足以满足您的目的。
我应该注意到,我从未真正看到过API中使用的这种技术,这只是我在阅读你的问题时想到的一个想法。
其他提示
文档。例如,
/**
* Test suite constructor.
* @param name test suite name cstring, shared
*/
TestSuite(char const *name) {
// ...
共享指针意味着指向的对象在此对象的生命周期内必须处于活动状态。
好吧,你可以使用一个std :: string来处理所有的内存分配
class TestSuite {
public:
TestSuite(const std::string &name):name_(name) {
}
~TestSuite() {
}
private:
std::string name_;
};
修改: 如果你想避免调用malloc(),你可以这样做:
class TestSuite {
public:
TestSuite(const char *name){
memcpy(name_, name, min(16, strlen(name));
}
private:
char name_[16];
};
这会浪费一些内存,但这可能是嵌入式平台上的一个问题。
拥有TestSuite的char name[XYZ]
<!>成员(XYZ足够大,可以轻松显示名称)并使用strncpy
复制字符串(最大长度为XYZ-1)。 / p>
为什么在拥有可以在构造函数中使用字符串文字或字符*的漂亮C ++字符串类时使用char *和malloc?
你能使用std :: string吗?您可以将它作为std::string name_
并让STL为您处理内存分配..
class TestSuite {
public:
TestSuite(const char* name) : name_(name) {}
~TestSuite() {}
private:
std::string name_;
};
不要忘记包含<string>
。