Avatar billede faramir Nybegynder
10. august 2004 - 15:57 Der er 20 kommentarer og
2 løsninger

Constructor/destructor - hvad er det?

Hej programmører!

Jeg er ved at lære c++ og er ved at være godt på vej men én ting irriterer mig. Jeg ved ikke 100% hvad en constructor og en destructor er og hvad formålet med dem er... Det står ikke godt forklaret i de bøger jeg har. Er der nogen der kan skære det ud i pap, både definitionen og brugen?
Avatar billede bufferzone Praktikant
10. august 2004 - 16:01 #1
Avatar billede faramir Nybegynder
10. august 2004 - 16:35 #2
Ja ok... Er der andre der evt kan uddybe det? -Også med brugen af disse?
Avatar billede soreno Praktikant
10. august 2004 - 16:35 #3
Når du laver et objekt så kaldes konstruktøren.
F.eks.
Bog *bog = new Bog();

Når du nedlægger et objekt kaldes destruktøren.
F.eks.
delete bog;

Du kan f.eks. bruge konstruktøren til at allokere memory (eller andre resourcer) og destruktøren til at deallokere.
Avatar billede soreno Praktikant
10. august 2004 - 16:39 #4
F.eks. kunne man forestille sig en vector (dynamisk array) der bla. havde følgende konstruktør/destruktør:

Vector::Vector()
{
    size = 0;
    maxSize = 10;
    array = new int[maxSize];
}

Vector::~Vector()
{
    delete [] array;
}

Det er muligt at overloade konstruktøren, men der kan kun være én destruktør.
Avatar billede faramir Nybegynder
10. august 2004 - 16:41 #5
Vil det sige at en constructor er det samme som en oprettelse af et hvert objekt? Fx. hvis jeg opretter en tilfældig variabel: int VarNavn; så skal man bare have i baghovedet at der bliver brugt en constructor til oprettelsen?
Avatar billede soreno Praktikant
10. august 2004 - 16:46 #6
Både og.

En int er en simpel datatype som ikke har tilknyttet metoder.

For et objekt gælder at når det initialiseres, så kaldes konstruktøren.

Prøv selv at eksperimentere lidt med hvornår konstruktør kaldes.

F.eks. noget ala (ikke testet):
Foo::Foo()
{
    cout << "Foo::Foo()" << endl;
}

Foo::~Foo()
{
    cout << "Foo::~Foo()" << endl;
}

Foo *foo;
cout << "test1" << endl;
foo = new Foo();
cout << "test2" << endl;
delete foo;
cout << "test3" << endl;

Og ligeledes ved metodekald:
void test()
{
  Foo foo;
}
Avatar billede soreno Praktikant
10. august 2004 - 16:51 #7
..så får du en ide om hvornår de kaldes.

En overloaded konstruktør kunne se sådan ud:
Foo::Foo(int n)
{
    cout << "Foo::Foo(" << n << ")" << endl;
}
Avatar billede soreno Praktikant
10. august 2004 - 16:53 #8
Det er også spændende at undersøge i hvilken rækkefølge konstruktør/destruktør kaldes i forbindelse med arv..
:-)
Avatar billede faramir Nybegynder
10. august 2004 - 18:19 #9
- Forstår det stadig ikke 100%. Har læst at hvis man ikke opretter nogen constructor/destructor så laver compileren selv nogen når man complierer projektet. Hvorfor så tage sig af selv at lave en constructor/destructor?
- Mente ellers at en erklæret variabel også var et objekt, der kan man bare se.
Avatar billede soreno Praktikant
10. august 2004 - 18:45 #10
Når man bruger resourcer, dvs. memory, filer og lign., så er det vigtigt at frigive resourcen når den ikke bruges mere (en computer består af et begrænset antal resourcer..).
Det er ofte oplagt at bruge destruktøreren til at frigive resourcen. På den måde er man sikret at destruktør metoden kaldes når objektet går ud af scope og dermed at brugeren af klassen ikke glemmer at frigive resourcer.

Hvis du f.eks. bruger en stl vector eller string, så vil den (formentlig) allokere en mængde memory når objektet initialiseres. Løbende vil mængden af memory stige (hvis der tilføjes til string eller vector). Når vector eller string går ud af scope så vil destruktøren kaldes og den allokerede memory vil blive frigivet.

Det er korrekt at compileren selv laver en konstruktør hvis du ikke gør det. Den er bare tom, dvs:
Klasse::Klasse() {}
Avatar billede faramir Nybegynder
10. august 2004 - 19:34 #11
Ok, men kan man så ikke bare lade den stå tom? Hvad er pointen med at lade den gøre noget når funktionen/klassen eller lign. kan sættes til det?
Der står også at compileren selv sørger for destructoren hvis programmøren ikke gør... Så kan man ikke bare helt glemme dem?
Hvis ikke, hvordan ved man så hvornår man skal kalde destructoren/constructoren og hvad der skal stå i dem?
Ved godt jeg stiller en masse dumme spørgsmål men kan bare ikke rigtig finde et sted at placere dem i forhold til alt det andet jeg har læst.
Avatar billede bertelbrander Novice
10. august 2004 - 20:30 #12
Jo, man kan godt glemme alt om constructorer og destructorer. Man kan også glemme alt om member funktioner, virtuelle funktioner og nedarvning og skrive alting i C.

Men det er en meget vigtig feature ved C++, og når man har lært sig fidusen vil man synes at alt andet er besværligt.

Den første ting man finder ud af bruge konstruktoren til er at initialisere sin class:

class Foo
{
public:
  Foo()
  {
    x = 0;
  }
  Foo(int _x)
  {
    x = _x;
  }
  int x;
};
 
Så kan man lave:

Foo foo; // Sætter foo.x = 0;
Foo *bar = new Foo(123); // Sætter bar->x = 123;

Det er lidt mere elegant (specielt når class'en bliver stor) end:
Foo foo;
foo.x = 0;
Foo *bar = new Foo;
bar->x = 123;
Avatar billede faramir Nybegynder
10. august 2004 - 20:37 #13
Ok, og destructoren skal i dette tilfælde kaldes hvornår?
Avatar billede bertelbrander Novice
10. august 2004 - 21:01 #14
Det mest almindelige at bruge en destructor til er til at frigive resourcer, f.ex. memory, filer, GDI-objekter...

I eksemplet ovenfor vil man ikke umidelbart bruge destructoren til noget, så man undlader den blot.

Man "kalder" aldrig en konstruktor eller destruktor, de bliver kaldt når et objekt bliver oprettet eller nedlagt.
Avatar billede faramir Nybegynder
10. august 2004 - 21:18 #15
... Dvs at når jeg har erklæret dem i fx en klasse så behøver jeg ikke gøre mere ved dem. Compileren styrer hvornår klassen ikke bruges mere?
Avatar billede bertelbrander Novice
10. august 2004 - 21:43 #16
Ja, prøv at køre soreno's eksempel fra "10/08-2004 16:46:22"
Avatar billede faramir Nybegynder
10. august 2004 - 21:48 #17
Ok så de skal bare være til stede i klassen så er alt godt. Fino. :-) Jeg prøver lige...
Avatar billede bertelbrander Novice
10. august 2004 - 21:51 #18
Et komplet eksempel:

#include <iostream>
#include <string>

class Foo
{
public:
  Foo(const char *s)
  {
      std::cout << s << std::endl;
      S = s;
  }
  ~Foo()
  {
      std::cout << "~" << S << std::endl;
  }
private:
  std::string S;
};

Foo foo1("Global");

int main()
{
  std::cout << "Start main" << std::endl;
  Foo foo2("Local");
  Foo *foo3 = new Foo("New'et");
  delete foo3;
  std::cout << "End main" << std::endl;
}
Avatar billede faramir Nybegynder
11. august 2004 - 15:32 #19
Hej drenge, har I læst mit nye spg? Jeg har fået en linker error efter at have nyinstalleret Borland C++ Builder 6 der lyder:

[Linker Error] Unresolved external '__InitVCL' referenced from C:\PROGRAMMER\BORLAND\CBUILDER6\LIB\CP32MTI.LIB|crtlvcl

[Linker Error] Unresolved external '__ExitVCL' referenced from C:\PROGRAMMER\BORLAND\CBUILDER6\LIB\CP32MTI.LIB|crtlvcl

Hvis I ved hvad det er der er galt gider I så skrive til mig i den anden tråd?:
http://www.eksperten.dk/spm/528277
Avatar billede faramir Nybegynder
07. januar 2005 - 13:55 #20
Lægger du lige et svar bertelbrander? I skal lige have en lille beløning hver. :-)
Avatar billede bertelbrander Novice
07. januar 2005 - 20:44 #21
Jeg samler ikke på point.
Avatar billede faramir Nybegynder
07. januar 2005 - 22:02 #22
Ok, så siger jeg bare mange tak for hjælpen!
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