De retour ifstream dans une fonction
Voici sans doute un très noobish question pour vous: Comment (si possible) puis-je retourner un ifstream à partir d'une fonction?
En gros, j'ai besoin d'obtenir le nom de fichier d'une base de données de l'utilisateur, et si la base de données avec le nom de fichier n'existe pas, alors j'ai besoin de créer ce fichier pour l'utilisateur. Je sais comment le faire, mais seulement en demandant à l'utilisateur de redémarrer le programme après avoir créé le fichier. Je voulais éviter que des inconvénients pour l'utilisateur, si possible, mais la fonction ci-dessous n'est pas compilé avec gcc:
ifstream getFile() {
string fileName;
cout << "Please enter in the name of the file you'd like to open: ";
cin >> fileName;
ifstream first(fileName.c_str());
if(first.fail()) {
cout << "File " << fileName << " not found.\n";
first.close();
ofstream second(fileName.c_str());
cout << "File created.\n";
second.close();
ifstream third(fileName.c_str());
return third; //compiler error here
}
else
return first;
}
EDIT: désolé, j'ai oublié de vous dire où et ce que l'erreur de compilation est:
main.cpp:45: note: synthesized method ‘std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(const std::basic_ifstream<char, std::char_traits<char> >&)’ first required here
EDIT: j'ai modifié la fonction de renvoyer un pointeur plutôt que Remus a suggéré, et modifié la ligne dans main () "ifstream base de données = *getFile()"; maintenant j'ai cette erreur à nouveau, mais cette fois dans la ligne dans le main():
main.cpp:27: note: synthesized method ‘std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(const std::basic_ifstream<char, std::char_traits<char> >&)’ first required here
OriginalL'auteur wrongusername | 2010-03-08
Vous devez vous connecter pour publier un commentaire.
Alors que cet extrait de code, peut-être de résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre post. Rappelez-vous que vous répondez à la question pour les lecteurs dans l'avenir, et ces personnes pourraient ne pas connaître les raisons de votre code suggestion.
OriginalL'auteur Corwin
Non, pas vraiment.
ifstream
ne possède pas de constructeur de copie, et si vous essayez de revenir un, cela signifie que la copie de l'instance dans votre fonction à l'endroit où le retour doit aller.L'habitude de contourner le problème est de passer d'une référence à l'un, et de modifier cette référence dans votre fonction.
Edit: si cela peut permettre à votre code fonctionne, il ne sera pas corrigé le problème de base. Maintenant, vous êtes de mélange deux responsabilités différentes en une seule fonction: 1) obtenir un nom de fichier, 2) ouvrir ou de créer ce fichier. Je pense que si vous vous séparez ces, le code sera plus simple, et de le rendre beaucoup plus facile à éliminer la source du problème que vous avez vu.
Edit 2: à l'Aide d'une référence comme cela fonctionne parfaitement sans un
operator=
. L'idée générale est quelque chose comme:De l'opérateur d'affectation est ni nécessaire ni utile dans le cas présent, nous utilisons simplement la fstream par la référence. Un
operator=
serait nécessaire si et seulement si nous avons dû passer à l'argument de la ctor. Avec un flux de données, nous pouvons défaut de construire un flux qui ne veut pas se connecter à un fichier, puis l'ouvrir pour se connecter au fichier après le fait.mais je pense qu'il ne me descendre pour qu'une erreur, cependant.
Le "truc" de passage dans une référence pour éviter de se retrouver un nouvel objet ne fonctionne que pour des types qui ont une
operator=
. std::ifstream ne l'a pas non plus, donc ce conseil ne fonctionnera pas pour vous.OriginalL'auteur Jerry Coffin
ifstream ne prend pas en charge la copie de construire sémantique (ce que le message d'erreur fondamentalement sais), donc vous ne pouvez pas retourner un ifstream. De retour d'un ifstream* au lieu de cela, et de transmettre à l'appelant la responsabilité de supprimer l'allocation de pointeur.
jamais, jamais, jamais de retour &stack_variable. Répartir la ifstream avec l'opérateur new et retourner le pointeur.
Tu veux dire quelque chose comme "ifstream returnStream = &premier; return returnStream;"? btw, cela ne fonctionne pas non plus. il me donne une erreur: "le principal.rpc:56: erreur: la conversion de ‘std::ifstream*’ pour non-scalaires de type ‘std::ifstream demandés par les principaux.rpc:57: erreur: invalid conversion from ‘void*’ to ‘std::ifstream*’"
Mal, j'ai très au sérieux et vous suggère fortement de lire sur le C/C++ gestion de la mémoire avant de continuer. Il y a juste beaucoup trop de choses que vous ne connaissez pas.
Merci! bien sûr...j'ai eu il y a longtemps, mais doit en ai oublié la plupart de celui-ci 🙂
OriginalL'auteur Remus Rusanu
Ce commentaire ne peut pas répondre à votre question, je veux juste demander à M. @Corwin à propos de sa réponse:
Tout comme son code, nous avons:
getFileName
bloc pour demander le nom de fichier, je pense que nous devrions code comme ceci (C'est mon avis seulement):Et dans
int main()
, je pense :Avec cela, vous pouvez obtenir
filename
de la saisie de l'utilisateur dans la console.Par les façons, merci Monsieur @Corwin pour le code sa m'aide beaucoup.
OriginalL'auteur Q.H.Chu
Comme une option, ifstream peut être étendu et personnalisé constructeur ajouté à la nouvelle classe.
Je l'ai étendu à créer le test flux de ressources, de l'encapsulation de test de recherche de ressources à l'intérieur d'elle.
OriginalL'auteur Nikita Karatun