alternative à strdup
Je suis en train d'écrire une classe C++ pour un livre qui contient un nom:
class Book {
private:
char* nm;
..........
............
..........
...........
};
Je ne suis pas autorisé à utiliser std::string
dans cette mission. Donc ici, je suis en utilisant strdup
pour copier la valeur du paramètre nom en nm dans le constructeur:
Book::Book(const char *name, int thickness, int weight)
: nm(NULL)
, thck(thickness)
, wght(weight)
{
if (name)
nm = strdup(name);
}
Est-il une alternative d'obtenir le même résultat sans l'aide de strdup
, mais en utilisant le mot-clé new
à la place?
Habituellement, vous devez utiliser
Pourquoi ne pouvez-vous pas simplement utiliser
c'est une contrainte sur la cession... je devrais peut-être ajouter un tag... et oui par STL je veux dire avec de la ficelle
probablement il devrait y avoir un autre tag
Cette affectation doit avoir été conçu avant strdup faisait partie de la bibliothèque standard. Sûrement la réponse à "Comment voulez-vous dupliquer une chaîne sans strdup?" doit être " Pourquoi serais-je?" 🙂
std::string
mais que voulez-vous dire exactement par "sans utiliser le C++ STL bibliothèque"? c'est à dire les parties de la bibliothèque standard sont que vous essayez d'éviter (et pourquoi)?Pourquoi ne pouvez-vous pas simplement utiliser
strdup
? Vous demandez un outil pour faire quelque chose, tout en refusant d'utiliser la solution idéale.c'est une contrainte sur la cession... je devrais peut-être ajouter un tag... et oui par STL je veux dire avec de la ficelle
probablement il devrait y avoir un autre tag
not-a-real-problem
...Cette affectation doit avoir été conçu avant strdup faisait partie de la bibliothèque standard. Sûrement la réponse à "Comment voulez-vous dupliquer une chaîne sans strdup?" doit être " Pourquoi serais-je?" 🙂
OriginalL'auteur aherlambang | 2010-03-14
Vous devez vous connecter pour publier un commentaire.
À proprement parler: Le
string
classe fait partie des Chaînes de la bibliothèque. C'est beaucoup plus facile à utiliser, de nature dynamique, et vous avez moins de soucis lors de la copie/l'attribution de C-style chaînes.L'autre approche consiste à copier manuellement:
Le problème avec cette approche est que vous aurez à gérer la mémoire vous-même et de mettre en œuvre tous les Grands l'un des trois fonctions de membre de toi (et de s'assurer de l'exception de sécurité autant que vous le pouvez).
Vous n'avez pas à vérifier
if (p)
aprèsnew
, parce que seulement nothrow nouveau peut retourner un pointeur null. Vous n'avez pas à libérer l'ancien tableau dansoperator=
. Copie-et-swap est généralement mieux.Oui, le deuxième était une faute de frappe. L'ancien j'ai voulu mettre un commentaire. (Je suppose que l'OP est de travailler dans un environnement restreint et ne peuvent pas avoir accès à la gestion des exceptions.)
Je pense que supprimer p est destiné à être delete [] nm. Comment, par ailleurs, à propos d'un set_string fonction au lieu de copier et de coller le code.
et une fois que vous avez set_string, vous pouvez décider de réutiliser nm si il est assez grand pour la prochaine chaîne de caractères, etc (au lieu d'allouer une nouvelle et jeter l'ancien)
OriginalL'auteur dirkgently
Pas vraiment une réponse, mais une correction à dirkgently qui ne rentre pas dans un commentaire: vous ne devriez pas écrire autant de code comme il l'a fait.
Sûr l'objet de la copie n'est pas quelque chose que vous voulez obtenir trop mal, bien que dans la vraie vie, la meilleure façon d'éviter cela est bien sûr d'utiliser la bibliothèque de classes dans la première place. Cela dit, un simple C-chaîne de style est un exemple comme un autre chose à la pratique avec:
Voir le "ne jetez pas une exception!" avertissement dans le constructeur? C'est parce que si vous le faites, la chaîne sera coulé. Si vous avez besoin de plus de ressources dans votre classe qui nécessite explicite libérer, c'est quand les choses deviennent vraiment pénible. La bonne chose à faire est d'écrire une classe juste pour le but de la tenue de la chaîne, et un autre pour le but de tenir les autres ressources, et d'avoir un membre de chaque type dans votre Livre de classe. Ensuite, vous n'avez pas à vous soucier des exceptions dans le constructeur, parce que les membres qui ont été construits sont détruits si le corps du constructeur de la classe conteneur lancers. Une fois que vous avez effectué ce une couple de fois, vous serez assez enclins à utiliser les bibliothèques standard et TR1.
Normalement, pour économiser les efforts que vous auriez du commencer par faire votre classe non-copiable, et seulement de mettre en œuvre le constructeur de copie et l'opérateur= si il s'avère que vous en avez besoin:
De toute façon,
strdup
est pas un grand mystère. Voici un couple de très semblables (à la fois de GNU), tout en recherchant "strdup.c". La même approche fonctionne habituellement pour les autres chaîne de fonctions de gestion, et en général tout ce qui ne nécessite pas de plate-forme spéciale dépendant de mécanismes de mise en œuvre: recherchez "function_name.c" et vous trouverez probablement une implémentation GNU qui explique comment c'est fait, et comment vous pouvez faire la même, mais des choses différentes. Dans ce cas, vous auriez du commencer par leur code et remplacer l'appel àmalloc
et la gestion des erreurs.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
OriginalL'auteur
Oui il y a une alternative.
nm
à votre alloué tableauOu vous pouvez utiliser
strdup
- btwstrdup
ne fait pas partie deC++ STL
.OriginalL'auteur stefanB
Vous avez à malloc avec strlen () et ensuite utiliser strcopy. Stupide devoirs btw.
OriginalL'auteur ypnos
Oh pinaise! Merci - c'est fixé maintenant.
OriginalL'auteur JBRWilkinson