在ArduinoUnit单元测试库我提供了一个机制,让一些测试程序的名称。 图书馆的用户可以编写如下:
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*
,构造可以使整个字符串的副本。
请注意,仍然可以通过传递一个颠覆了这一机制const 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];
};
然而,这会浪费一些内存,它可以在嵌入式平台上的问题。
有char name[XYZ]
您的TestSuite的构件(具有足够的XYZ大,以舒适地显示名称),并使用strncpy
复制串(用XYZ-1的最大长度)。
你为什么要使用的char *)和malloc(当你有很不错的C ++字符串类,它可以接受一个字符串字面或在其构造一个char *?
您可以使用的std :: string? 你可以把它当作std::string name_
,并有STL照顾的内存分配给你..
class TestSuite {
public:
TestSuite(const char* name) : name_(name) {}
~TestSuite() {}
private:
std::string name_;
};
不要忘了包括<string>
。
参考
文章来源: How can I prevent the need to copy strings passed to a avr-gcc C++ constructor?