不是一个真正的答案,而是对dirkgently的更正,无法在评论中适合:你真的不应该写那么多代码。
安全对象复制不是您想要过于错误的东西,尽管在现实生活中,避免这种情况的最佳方法当然是首先使用适当的库类。 话虽如此,一个简单的C风格字符串就像任何其他东西一样好练习:
class Book {
char *nm;
public:
Book(const char *name) : nm(copystr(name)) { }
Book(const Book &o) : nm(copystr(o.nm)) { }
~Book() { delete[] nm; }
Book& operator=(const Book &o) {
Book cp = o;
swap(cp);
return *this;
}
void swap(Book &o) {
std::swap(this->nm, o.nm);
}
};
char *copystr(const char *name) {
if (!name) return 0;
char *newname = new char[strlen(name)+1];
std::strcpy(newname, name);
return newname;
}
在构造函数中看到“不要抛出异常!”的警告吗?那是因为如果你这样做,字符串就会泄漏。如果你的类需要多个需要显式释放的资源,那么事情就变得非常繁琐了。正确的做法是编写一个专门用于保存字符串的类,另外一个专门用于保存其他资源的类,并在Book类中有每种类型的一个成员。然后你就不必担心构造函数中的异常了,因为如果包含类的构造函数体抛出异常,则已构造的成员将被析构。一旦你做了几次,你就会很乐意使用标准库和TR1。
通常,为了节省精力,你应该首先使你的类不可复制,并只在需要时实现复制构造函数和operator=:
class Book {
char *nm;
public:
Book(const char *name) : nm(copystr(name)) { }
~Book() { delete[] nm; }
private:
Book(const Book &o);
Book& operator=(const Book &o);
};
无论如何,
strdup
并不是什么神秘的东西。这里有几个非常相似的实现(都来自GNU),只需搜索“strdup.c”即可。同样的方法通常适用于其他字符串处理函数,以及一般不需要特殊平台相关机制来实现的任何东西:查找“function_name.c”,你可能会找到一个GNU实现来解释它是如何完成的,以及如何做出类似但不同的事情。在这种情况下,您可以从他们的代码开始,替换对
malloc
和错误处理的调用。
http://www.koders.com/c/fidF16762E3999BA95A0B5D87AECB0525BA67CEE45A.aspx
http://cvs.frodo.looijaard.name/viewvc/cgi-bin/viewvc.cgi/public/psiconv/compat/strdup.c?revision=1.1.1.1&view=markup
std::string
,但是“不使用C++ STL库”究竟是什么意思?即您要避免使用标准库的哪些部分(以及为什么)? - CB Baileystrdup
?你正在寻求一种工具来完成某件事情,却拒绝使用最理想的工具。 - Ben S不是真正的问题
... - stefanB