2010-10-02 6 views
3

j'ai un problème avec ce code:C++ std :: ifstream dans le problème du constructeur

#include <fstream> 

struct A 
{ 
    A(std::ifstream input) 
    { 
     //some actions 
    } 
}; 

int main() 
{ 
    std::ifstream input("somefile.xxx"); 

    while (input.good()) 
    { 
     A(input); 
    } 

    return 0; 
} 

G ++ me sorties ceci:

$ g++ file.cpp 
file.cpp: In function `int main()': 
file.cpp:17: error: no matching function for call to `A::A()' 
file.cpp:4: note: candidates are: A::A(const A&) 
file.cpp:6: note:     A::A(std::ifstream) 

Après avoir changé à cela, il compiler (mais ne résout pas le problème):

#include <fstream> 

struct A 
{ 
    A(int a) 
    { 
     //some actions 
    } 
}; 

int main() 
{ 
    std::ifstream input("dane.dat"); 

    while (input.good()) 
    { 
     A(5); 
    } 

    return 0; 
} 

Quelqu'un peut-il m'expliquer ce qui ne va pas et comment le réparer? Merci.

Répondre

8

Deux bugs:

  • ifstream n'est pas copiable (changer le paramètre du constructeur à une référence).
  • A(input); est équivalent à A input;. Ainsi, le compilateur essaie d'appeler le constructeur par défaut. Envelopper les parens autour de (A(input));. Ou donnez-lui simplement un nom A a(input);.

Aussi, quel est le problème avec l'utilisation d'une fonction pour cela? Seul le constructeur de la classe est utilisé semble-t-il, que vous semble abuser en tant que fonction renvoyant void.

+0

Est-ce que A (entrée) ne construit pas un objet A temporaire? –

+1

@Martin Les parenthèses autour de 'input' sont les parenthèses de liaison utilisées dans les déclarateurs, par exemple comme elles apparaissent dans' void (* p)(); 'autour de' * p'.Ceux autour de 'input' sont redondants. C'est ce que les gens expérimentent parfois dans le vecteur p (istream_iterator (cin), ...); ', où des parenthèses redondantes sont spécifiées autour de' cin'. –

+0

J'ai oublié de mentionner que j'ai essayé cette chose avec des références. (A (entrée)) était bug, merci. – darvan

4

ifstream n'a pas de constructeur de copie. A(std::ifstream input) signifie "constructeur pour A en prenant un ifstreampar la valeur." Cela nécessite que le compilateur fasse une copie du flux à transmettre au constructeur, ce qu'il ne peut faire car aucune opération n'existe.

Vous devez transmettre le flux par référence (ce qui signifie "utiliser le même objet de flux, et non une copie de celui-ci.") Changez donc la signature du constructeur en A(std::ifstream& input). Notez l'esperluette, qui signifie « référence » et, dans le cas des paramètres de la fonction, signifie « passer ce paramètre par référence plutôt que par la valeur


Note Stylistic. Le corps de votre while boucle, A(input);, construit une structure de type A, qui est ensuite presque immédiatement détruit lorsque la boucle while boucle.Etes-vous sûr que c'est ce que vous voulez faire? Si ce code est complet, alors il serait plus logique de faire cela une fonction ou une fonction membre de A construite en dehors la boucle:

static void process(std::istream& stream) 
{ 
    // some actions 
    // note stream is declared as std::istream&; this lets you pass 
    // streams that are *not* file-based, if you need to 
} 

int main() 
{ 
    std::ifstream input("somefile.xxx"); 

    while (input.good()) 
    { 
     process(input); 
    } 

    return 0; 
} 

OU

struct A 
{ 
    A() 
    { 
     // default constructor for struct A 
    } 

    void process(std::istream& stream) 
    { 
     // some actions 
    } 
}; 

int main() 
{ 
    std::ifstream input("somefile.xxx"); 

    A something; 
    while (input.good()) 
    { 
     something.process(input); 
    } 

    return 0; 
} 
2

Les flux ne sont pas copiables.

Vous devez donc passer par référence.

struct A 
{ 
    A(std::ifstream& input) 
       ^^^^^ 
    { 
     //some actions 
    } 
}; 
Questions connexes