Avatar billede hurra Novice
16. august 2005 - 19:43 Der er 16 kommentarer og
1 løsning

Constructor der initializere en struct

Hvordan gør jeg det her:

struct TSettings
{
  public:
      TTest *Owner;
      int top;
      int left;
      TSettings(TTest *lOwner);

  TSettings& operator =(const TSettings &lfs);
};
class TTest
{
  private:
      int pTop, pLeft;
  public:
      TTest() : TSettings(); //<-- Her er fejlen
      TSettings settings;
      UpdateSettings();

};
TTest::TTest() : TSettings(this)
{
}
Og så får jeg fejlen [C++ Error] Unit1.h(30): E2312 'TSettings' is not an unambiguous base class of 'TTest'
Avatar billede arne_v Ekspert
16. august 2005 - 19:45 #1
class TTest
{
  private:
      int pTop, pLeft;
  public:
      TTest();
      TSettings settings;
      UpdateSettings();

};
TTest::TTest() : settings(this)
{
}

men jeg ved ikke om man må bruge this så tidligt
Avatar billede hurra Novice
16. august 2005 - 19:48 #2
Ahhh, jeg havde T med i settings. Du skal også ha nogle points.
Avatar billede arne_v Ekspert
16. august 2005 - 19:49 #3
virker det ?

ja det er feltnavnet ikke typen der skal angives
Avatar billede bertelbrander Praktikant
16. august 2005 - 19:51 #4
Man kan godt bruge this så tidligt, men der er nogen kompilere der vil give en warning, da man bruger et object der kun er delvist initialiseret.
Avatar billede hurra Novice
16. august 2005 - 19:54 #5
Ja, det er helt vildt :) Også det andet problem jeg nåede at nævne i det forige spørgsmål (http://www.eksperten.dk/spm/640623) opdagede jeg lige :)

Vildt!!!

Så vil jeg hjem og ha noget aftensmad. Tak for hjælpen.
Avatar billede hurra Novice
16. august 2005 - 19:55 #6
Hedder det her initializerings stas forresten ngoet bestemt ? og kunne man ha haft flere ting på ? Fx:
TTest::TTest() : settings(this) : noget(this)
Avatar billede bertelbrander Praktikant
16. august 2005 - 19:58 #7
Det hedder vist bare "initializer list".
Bemærk at du kun skal have : før den første, men , mellem de andre
Avatar billede arne_v Ekspert
16. august 2005 - 20:02 #8
der er sågar nogen som foretrækker at bruge det på simple data typer:

int a;
int b;
X() : a(123),b(456)
{
...
}
Avatar billede arne_v Ekspert
16. august 2005 - 20:03 #9
og et svar
Avatar billede amma Nybegynder
18. august 2005 - 10:35 #10
Ja, at bruge 'this' før constructoren er initaliseret giver 'undefined results'.

Istedet kan du gøre:

class TTest2
{
  private:
      TTest m_Testen;
      TSettings m_Settings
  public:
      TTest2() : m_Settings(m_Testen)
      {
      }
};

Sådan undgår du at bruge 'this' pointeren før den eksisterer.
Avatar billede bertelbrander Praktikant
19. august 2005 - 00:40 #11
>amma, en lille korrektion.
this pointern eksisterer når konstructoren bliver kaldt og den peger på valid memory, men indholdet er ikke initialiseret.
At bruge this i constructoren giver ikke "undefined results", at bruge det den peger på kan.
Jeg har svært ved at se hvordan dit "fix" løser nogen problemer.
Avatar billede amma Nybegynder
19. august 2005 - 09:38 #12
Til bertelbrander

Der er nu en grund til at vc++ giver en warning omkring det her. Grunden til det er selvfølgelig at hvis TSettings' konstruktor begynder at bruge variabler fra TTest går det galt.

Håber det giver mening.
Avatar billede bertelbrander Praktikant
19. august 2005 - 20:04 #13
Nej, det giver ikke mening.
Hvad sker der i dit eksempel hvis du bytter om på m_Testen & m_Settings i class'en? Eller bruger følgende:
  public:
      TTest2() : m_Testen(m_Settings), m_Settings(m_Testen)
      {
      }
Så har du sansynligvis et problem => At bruge this i "intitializer list" er ikke et større problem.

Det er ikke første gang en kompiler giver ubrugelige warnings.
Avatar billede amma Nybegynder
21. august 2005 - 10:36 #14
Jeg forstår ikke helt. Hvis du bytter om, bliver problemstillingen jo en anden! Det er ikke det, det originale spørgsmål omhandlede. Jeg har blot løst dette problem, som det bør løses.

Og nej, kompiler warnings er aldrig ubrugelige. Det er f.eks. mere end dårlig praksis at pragma warnings ud. -Eneste undtagelse er når compileren ikke understøtter alle features i C++ og derfor brokker sig. Fra og med MSVC++ 2003 er dette dog ikke noget problem.


Mvh.
Asger
Avatar billede bertelbrander Praktikant
21. august 2005 - 14:28 #15
Et lille eksempel der viser at man kan være nødt til at bruge this i initializer list:
#include <iostream>
class A
{
public:
  A(class B *owner) : MyOwner(owner)
  { }
  B * const MyOwner;
};

class B
{
public:
  B() : a(this) {}
  A a;
};

int main()
{
  B b;
}

Her er man nødt til at bruge en pragma for at disable den tåbelige warning.
Avatar billede amma Nybegynder
21. august 2005 - 17:16 #16
bertelbrander, dit nye eksempel er en kopi af det originale spm. Min metode vil derfor også virke på dit nye eksempel. Brug en klasse, C, som proxy istedet for direkte som nu.
Avatar billede bertelbrander Praktikant
21. august 2005 - 20:11 #17
Hvorfor skal jeg ændre på mit design fordi nogen opfinder tåbelige warnings?
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