Avatar billede clone Nybegynder
16. februar 2001 - 13:05 Der er 10 kommentarer

Hvad sker der her?

Jeg studsede lige over følgende kode:

ifstream in(\"test.txt\", ios::in);
if (!in) {
  printf(\"Error: Can\'t open file\");
}

Hvilken member-funktion i \"in\" gør det egentlig muligt at \"spørge på den\" i if-sætningen??
Hvis \"in\" var en pointer ville det give mening, men det er den jo ikke.
Avatar billede seider Nybegynder
16. februar 2001 - 13:10 #1
du spørger på om in eksistere (!in), hvis den ikke findes så fejlmelding.

/* seider */
Avatar billede pstric Nybegynder
16. februar 2001 - 13:10 #2
ifstream in(\"test.txt\", ios::in); // kalder ifstream (inputfilestream)\'s constructor og opretter in
if (!in) { // Hvis constructoren fejlede
  printf(\"Error: Can\'t open file\");
}

Avatar billede clone Nybegynder
16. februar 2001 - 16:40 #3
pstric skriver: \"hvis constructoren fejlede\" hmmm... lyder mystisk! Så vidt jeg ved returnerer en constructor ikke nogen værdi - eller tager jeg helt fejl?
Det var DET jeg undrede mig over.
Avatar billede pstric Nybegynder
16. februar 2001 - 18:16 #4
Jamen clone, det er jo også idéen i en constructor. Du giver constructoren de parametre, den skal bruge og så opretter den et nyt objekt af den angivne type.

I dette tilfælde er parametrene en \'const char *\' og en \'ios_base::openmode\' og in bliver tildelt et nyt objekt af typen ifstream.

Hvis ifstream constructoren ikke kan åbne den angivne fil (den kalder open()), så opretter den ikke et nyt objekt, og lader være med at tildele en værdi til in. Derfor kan du efter kaldet til constructoren afgøre om objektet blev oprettet ved at undersøge om værdien af in = null (i linien if (!in)).
Avatar billede clone Nybegynder
17. februar 2001 - 00:54 #5
Ok, det ved jeg egentlig godt. Men, hvordan ser koden så ud, hvis man selv skal skrive den?
Avatar billede pstric Nybegynder
17. februar 2001 - 00:56 #6
Hvis man selv skal skrive hvad?
Avatar billede clone Nybegynder
17. februar 2001 - 00:58 #7
Hvordan vil du selv lave en constructor, som giver du den mulighed?
Avatar billede clone Nybegynder
17. februar 2001 - 01:08 #8
Jeg har en klasse som jeg bruger til at parse en tekst-fil med. Denne klasse indeholder en C FILE pointer, som jeg bruger til at indlæse data fra tekst-filen.
Jeg opretter objektet med følgende kode:

CMyInFile inFile; // create infile object

Klassens constructor sørger for at oprette en filehandle ud fra ovenstående pointer. Hvis ikke filen kan åbnes med fopen() så er min fil-pointer NULL.
Det som mit egentlige spørgsmål drejer sig om er, at jeg gerne vil have mulighed for at checke om filen er åben på samme måde som den metode jeg beskrev i første indlæg. Altså:

CMyInFile inFile; // create infile object
if (!inFile) {
  printf(\"Error: Can\'t open file\");
}
Avatar billede krisballe Nybegynder
19. februar 2001 - 23:25 #9
Hej
For lige at svare på dit første indlæg. Årsagen til at det kan lade sig gøre at bruge udtrykket:
if(!in)...
er at alt der er databærende i C++ (variabler, instanser, pointere, osv.) kan evalueres til enten sandt eller falsk. da \"in\" i dette tilfælde er en instans af objektet ifstream, kan der evalueres på det. Hvis det lykkedes at instantiere instansen er det \"true\" ellers er det NULL eller \"false\". Konstruktøren i ifstream er skruet sammen således at den kun returnerer et nyt objekt hvis den pågældende fil i første inputparameter findes, og kan åbnes. Og ja... implicit returnerer en kontruktør et objekt af selv sig. Returneringen er transparant for brugeren af konstruktøren, men hvis du lige leder tanken hen på \"this\", vil du sikkert se ideen. Lige så snart konstruktøren går ud af scope, returneres \"this\" til ejeren af objektet.
Bjarne Stoustrup har forklaret princippet i konstruktøren i flere af hans bøger.

Dit sidste indlæg:
Den metode jeg selv benytter er en temporær ifstream instans i en try-catch blok.

...snippet
public bool CMyInFile::Testfile(char[] file)
{
try
{
  ifstream ifTemp(file, ios::in);
}
catch (...)
{
    return false;

return true;
}

herefter vil du kunne spørge på:
if(!infile.TestFile(\"testfile.txt\")
{
  cout << \"Could not open testfile.txt\" << endl;
}
else
{
  ...instantier FILE objektet....
}
Avatar billede soepro Nybegynder
22. februar 2001 - 09:54 #10
Det kan IKKE lade sig gøre at lave en constructor som ikke opretter en instans af klassen !!! Hvad man derimod kan lave, er at overloade ! og != (not og not equal) operator\'erne for klassen, sådan at d.o. check på !in giver mening - nemlig at det filehandle, som givet ligger \"inde i\" ifstream klassen er NULL.

Følgende eksempel viser teknikken (grader Kelvin kan ikke være negative, derfor betragtes instanser hvor temperatur er mindre end 0 så \"ikke oprettede\"):

class TempKelvin
{
  private:
  int iTemp;
  public:
  TempKelvin(void) { iTemp = 0; };
  TempKelvin(int vTemp) { if (vTemp >= 0) iTemp = vTemp; else iTemp = -1; };
  bool operator !() { return iTemp >= 0; };
};

Så kan man efterfølgende laver dette check:

:
TempKelvin T1(12);
TempKelvin T2(-10);
if (!T2)
  return ;// error !!
:
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester