Avatar billede krismort Nybegynder
18. juli 2005 - 12:55 Der er 18 kommentarer og
1 løsning

initialisering af members attributter i kontruktøren.

Hej,
Hvad er forskellen på disse to initialiseringer af member attributter i konstruktøren ?

class C {
public:
  C():member1(0), member2(0) {}
private:
int member1;
int member2;
};

class C {
public:
  C() { member1 = 0; member2 = 0; }
private:
int member1;
int member2;
};
Avatar billede arne_v Ekspert
18. juli 2005 - 13:01 #1
ingen

men den sidste syntax virker kun på simple data typer (inkl. pointere til objekter)
Avatar billede arne_v Ekspert
18. juli 2005 - 13:02 #2
[det er iøvrigt en af grundene til at jeg så godt som aldrig bruger
members som er classes - kun pointere til classes]
Avatar billede peterkn Nybegynder
19. juli 2005 - 01:48 #3
const og reference members kan kun initialiseres og derfor skal første metode anvendes på den slags.
Initialiseringerne bør (skal) ske i samme rækkefølge som erklæringerne.

Den anden metode kan naturligvis anvendes på alle slags member objekter, blot objektet har defineret en gyldig assignment-operator.
Avatar billede arne_v Ekspert
19. juli 2005 - 18:43 #4
jeg vil MEGET gerne se et eksempel på to klasser hvor den ene klasse har en
member (altså ikke en pointer) af den anden klasse hvor den anden klasse
ikke har en constuctor uden argumenter compile med den anden metode
Avatar billede amma Nybegynder
21. juli 2005 - 19:11 #5
Hej.

Jeg kan pure afvise at ..

"Initialiseringerne bør (skal) ske i samme rækkefølge som erklæringerne"

det er ikke rigtigt.


Nu mit "rigtige" svar:
Der er ingen forskel i nævnte eksempel. Her er dit eksempel som svar på din sidste kommentar:

class A {
public:
  A( int _1):member1(_1), member2(0) {}
private:
int member1;
int member2;
};

class B {
public:
  B() : member2(123) { member1 = 0; }
private:
int member1;
A member2;
};

class C {
public:
  C() : member1(0), member2(123) {}
private:
int member1;
A member2;
};


Hvor klassen 'B' gør præcis hvad du spørger om, og klassen 'C' er den mest korrekte måde.


Mvh.
Asger
Avatar billede arne_v Ekspert
21. juli 2005 - 19:59 #6
det var min kommentar - ikke spørgers

og klasse B gør ikke det jeg spørger om (du initialiserer netop member2 udenfor
ikke indenfor)

min kommentar var ren drilleri - det kan nemlig ikke lade sig gøre i C++
Avatar billede amma Nybegynder
21. juli 2005 - 20:18 #7
Så forklar venligst dit spørgsmål igen ... du nævnte jo ikke noget omkring indenfor/udenfor.


mvh.
Avatar billede arne_v Ekspert
21. juli 2005 - 20:31 #8
nej - jeg snakker om anden metode (anden metode har initialiseringen indenfor - første
metode har initialiseringen udenfor)
Avatar billede amma Nybegynder
21. juli 2005 - 20:42 #9
nåhh! nej det er rigtigt, det kan man ikke.

Men du kunne f.eks. skrive;


struct A
{

CValueInit<int, 123123> m_member1;
};

dette ville gi' dig en int med 123123 som start værdi. Med den rette teknik behøver det ikke at fylde mere eller være langsommere.

mvh.
Avatar billede peterkn Nybegynder
21. juli 2005 - 23:26 #10
amma>
Jeg kan pure afvise at ..
"Initialiseringerne bør (skal) ske i samme rækkefølge som erklæringerne"
det er ikke rigtigt.

Så prøv venligst følgende eksempel (kompileret med Visual C++ 7)


#include "stdio.h"

class Foo
{
public:
  Foo() : c(3), b(c-1), a(b-1) {};
  Foo(int x) : a(1), b(a+1), c(b+1) {};
  int a,b,c;
};

int main(int argc, char* argv[])
{
  Foo Bar1;
  printf("Bar1: a=%d, b=%d, c=%d\n",Bar1.a,Bar1.b,Bar1.c);

  Foo Bar2(1);
  printf("Bar2: a=%d, b=%d, c=%d\n",Bar2.a,Bar2.b,Bar2.c);

  return 0;
}


med output

  Bar1: a=-858993461, b=-858993461, c=3
  Bar2: a=1, b=2, c=3

Såehhh.. rækkefølgen er altså ikke ligegyldig.

Læs f.eks

  Scott Meyers
  "Effective C++, 50 Specific Ways to Improve Your Programs ans Designs"

Item 12 behandler dette emne.


Mvh
Avatar billede arne_v Ekspert
21. juli 2005 - 23:40 #11
I min 2ed 1998 er det altså Item 13 - og lige netop i den slags tilfælde (dependency
mellem initialiseringer) vil jeg klart foretrække assignments inde i constructor
fordi der er det netop krystal klart hvad der sker i hvilken rækkefølge

Og de performance hensyn han mener taler for initialisering udenfor i Item 12 (i min
udgave) vil jeg til enhver tid totalt ignorere for at få mere letlæselig kode.
Avatar billede peterkn Nybegynder
21. juli 2005 - 23:42 #12
arne_v>

Kan du forklare

"men den sidste syntax virker kun på simple data typer (inkl. pointere til objekter)"

lidt nærmere ?


Mvh
Avatar billede peterkn Nybegynder
21. juli 2005 - 23:45 #13
Jeg har første udgave af Scott Meyers bog, 1992.
Jeg foretrækker iøvrigt også metode 2.


Mvh
Avatar billede arne_v Ekspert
21. juli 2005 - 23:47 #14
eksempel som ikke compiler:

class A
{
  public:
      A(int v) { };
};

class B
{
  private:
      A m_a;
  public:
      B(A a) { m_a = a; };
};
Avatar billede amma Nybegynder
22. juli 2005 - 11:47 #15
Svar til:
Jeg kan pure afvise at ..
"Initialiseringerne bør (skal) ske i samme rækkefølge som erklæringerne"
det er ikke rigtigt.

Så prøv venligst følgende eksempel (kompileret med Visual C++ 7)

Det er ikke det, dit eksempel gør. Erklæringerne er denne del:
  int a,b,c;

initialiseringerne af disse kan ske i vilkårlig rækkefølge, som dit eksempel også viser. At resultatet så bliver forskelligt fra hvad man måske skulle tro modsiger ikke min påstand.
Avatar billede arne_v Ekspert
22. juli 2005 - 12:00 #16
der er visse semantiske forskelle i "bør" og "kan" ...
Avatar billede bertelbrander Novice
23. juli 2005 - 19:31 #17
Hvis dine members er af typen int (eller andre simple typer) er der ingen forskel.
Men hvis dine members var af typen X:

class X
{
public:
  X(int){ std::cout << "X::X(int)" << std::endl; }
  X(){ std::cout << "X::X()" << std::endl; }
  X & operator = (int) {std::cout << "X:: = " << std::endl; return *this; }
};

Kan du se at der for det første eksempel kun bliver kaldt int constructoren X::X(int)
I det andet tilfælde bliver default constructoren X::X() først kaldt, derpå bliver assignment operatoren kaldt (X::=(int)).
Det ses let at den første metode er mest effiktiv.
Avatar billede vivian22 Nybegynder
22. juli 2012 - 01:44 #18
SPAM fjernet

Dette indlæg er blevet modereret af en CoAdmin

Avatar billede vivian22 Nybegynder
22. juli 2012 - 01:46 #19
SPAM fjernet
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