strdup 的替代方案
我正在为一本包含名称的书编写一个 C++ 类:
class Book {
private:
char* nm;
..........
............
..........
...........
};
在此作业中不允许使用 std::string
。因此,这里我使用 strdup
将参数名称的值复制到构造函数中的 nm 中:
Book::Book(const char *name, int thickness, int weight)
: nm(NULL)
, thck(thickness)
, wght(weight)
{
if (name)
nm = strdup(name);
}
是否有一种替代方法可以在不使用 strdup
的情况下实现相同的结果,但使用关键字 new
代替?
I'm writing a C++ class for a book that contains a name:
class Book {
private:
char* nm;
..........
............
..........
...........
};
I am not allowed to use std::string
in this assignment. So here I am using strdup
to copy the value of the parameter name into nm in the constructor:
Book::Book(const char *name, int thickness, int weight)
: nm(NULL)
, thck(thickness)
, wght(weight)
{
if (name)
nm = strdup(name);
}
Is there an alternative of achieving the same result without using strdup
, but using the keyword new
instead?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
严格来说:
string
类是 Strings 库的一部分。这更容易使用,本质上是动态的,并且与 C 样式字符串相比,您在复制/分配时不必担心。另一种方法是手动复制:
这种方法的问题是您必须自己管理内存并自己实现所有三大特殊成员函数(并尽可能确保异常安全)。
Strictly speaking: The
string
class is part of the Strings library. This is much easier to use, dynamic in nature and you have less worry when copying/assigning than C-style strings.The other approach is to manually copy out:
The problem with this approach is that you will have to manage the memory yourself and implement all the Big-three special member functions yourself (and ensure exception-safety as much as you can).
不是真正的答案,而是对不适合评论的 dirkgently 的更正:你真的不应该像他那样编写那么多代码。
安全的对象复制并不是您希望犯的严重错误,尽管在现实生活中,避免这种情况的最佳方法当然是首先使用适当的库类。也就是说,简单的 C 风格字符串与其他任何练习一样都是一个很好的示例:
请参阅“不要抛出异常!”构造函数中的警告?那是因为如果你这样做,字符串就会泄漏。如果您的类中需要多个需要显式释放的资源,那么事情就会变得非常乏味。正确的做法是编写一个类只是为了保存字符串,另一个类是为了保存其他资源,并且在 Book 类中为每种类型都有一个成员。那么你就不必担心构造函数中的异常,因为如果包含类的构造函数体抛出异常,则已构造的成员将被破坏。一旦您这样做了几次,您就会非常热衷于使用标准库和 TR1。
通常,为了节省精力,您首先要使类不可复制,并且仅在需要时才实现复制构造函数和运算符=:
无论如何,
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
Not really an answer, but a correction to dirkgently's that won't fit in a comment: you really shouldn't write so much code as he did.
Safe object copying isn't something you want to get too badly wrong, although in real life the best way to avoid that is of course to use the appropriate library classes in the first place. That said, a simple C-style string is as good an example as anything else to practice with:
See the "don't throw an exception!" warning in the constructor? That's because if you do, the string will be leaked. If you need more than one resource in your class that requires explicit freeing, that's when things become really tedious. The right thing to do is to write a class just for the purpose of holding the string, and another one for the purpose of holding the other resource, and have one member of each type in your Book class. Then you don't have to worry about exceptions in the constructor, because members which have been constructed are destructed if the constructor body of the containing class throws. Once you've done this a couple of times, you'll be pretty keen to use the standard libraries and TR1.
Normally, to save effort you'd start by making your class non-copyable, and only implement the copy constructor and operator= if it turns out you need them:
Anyway,
strdup
is no great mystery. Here are a couple of very similar implementations (both from GNU), just by searching for "strdup.c". The same approach usually works for other string-handling functions, and in general anything that doesn't require special platform-dependent mechanisms to implement: look for "function_name.c" and you'll probably find a GNU implementation that explains how it's done, and how you can do similar but different things. In this case you'd start with their code and replace the call tomalloc
and the error-handling.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
是的,还有另一种选择。
nm
到您分配的位置array或者您可以使用
strdup
- 顺便说一句,strdup
不是C++ STL
的一部分。Yes there is an alternative.
nm
to your allocated arrayOr you could use
strdup
- btwstrdup
is not part ofC++ STL
.您必须使用 strlen 进行 malloc,然后使用 strcopy。顺便说一句,愚蠢的家庭作业。
You have to malloc with strlen and then use strcopy. Stupid homework btw.