Toon posts:

[C++] unresolved external symbol bij compilen.

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik krijg volgende fout bij het linken:
code:
1
LabelSoort.obj : error LNK2001: unresolved external symbol "private: static class CRoutenTab  CLabelSoort::routentab"


Dit is een (onderdeeltje van mijn) class:
C++:
1
2
3
4
5
class CLabelSoort
{
private:
  static  CRoutenTab routentab;
};


Nu bestaat de constructor 'CRoutenTab()' wel degelijk. Maar waarom word die fout nu gegeven?

Ik weet wel dat bvb "static int test;" geinitialiseerd moet worden met "CClass::test = 0;". Maar hoe moet ik een eigen custom class initten??

[ Voor 10% gewijzigd door Verwijderd op 31-10-2003 15:59 ]


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 31 oktober 2003 @ 15:57:
Ik weet wel dat bvb "static int test;" geinitialiseerd moet worden met "CClass::test = 0;". Maar hoe moet ik een eigen custom class initten??
Wat dacht je van
C++:
1
CRoutenTab           CLabelSoort::routentab;

:?

Professionele website nodig?


Verwijderd

Topicstarter
Perfect :D

Thx curry! ;)

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Vraag is nu (en dat was de reden van mijn :?-smiley): waarom wist je wel hoe het voor een static int moest, en niet voor een willekeurige andere static member? ;)

Professionele website nodig?


Verwijderd

Topicstarter
Int & string enzo is gemakkelijker als eigen classes hé ... Ik heb nagekeken op C++ anotations (of zoiet) en daar stond dus da met int's enzo op. Dan in mijn C++ paradigm boekske gekeken & daar stond er niets van in (eigen classes).

Vreemd hé... Maar nu weet ik da ;)

Maar nu zit ik met een ander probke bij mijn initialisatie van mijn classes...
Maar da zallek eerst wel zelf onderzoeken (daar leer ik meer uit)

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Alles is een class, ook een int, vandaar mijn vraag om dat begrip te kweken ;)

Puur technisch bezien is een int ook een class met constructors, operator overloads en alles erop en eraan. Dus vandaar dat je een willekeurige andere class overal op exact dezelfde manier als een int kunt en moet gebruiken.

Professionele website nodig?


Verwijderd

Topicstarter
Inderdaad, maar ik wou het initten met de standaard waarden. Bij een int moet je dan = 0 doen... waarbij 0 de eigen standaard waarde is. Maar ik wou die class met de echte puur ()-constructor initten. En dus geprobeert met routentab() etc etc... Maar gen enkel dink dat ik deed wou iets doen :)

Met jouw dink wel ;)

Verwijderd

Topicstarter
mja, hier geraak ik ook niet aan uit dus...

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CLabelSoort [<-- Base class]
{
private:
  CLabelSoort();
public:
  CLabelSoort( const LabelInformation_t &ltInfo );
};

[...snip...]

class CNormaalPakket : public CLabelSoort [<-- Derived class]
{
private:
  CNormaalPakket();
public:
  CNormaalPakket( const LabelInformation_t &ltInfo ) { }
};


daarop geeft hij de errormelding:
d:\tmp\dpd_dll\soortenlabels\normaalpakket.h(9) : error C2248: 'CLabelSoort::CLabelSoort' : cannot access private member declared in class 'CLabelSoort'
d:\tmp\dpd_dll\soortenlabels\labelsoort.h(30) : see declaration of 'CLabelSoort::CLabelSoort'

Ja akkoord! Dat is private... Maar ik wil niet dat die word aangeroepen. Ik wil dat als je een labelinfo_t doorstuurd naar NormaalPakket dat die de respectievelijke CLabelSoort-constructor aanroept. Wat hij dus niet doet... Hij probeert de ()-constructor aan te roepen (ik heb het in debug-mode eens volledig nagetrokken en hij gaat dus van "CNormaalPakket( ltInfo )" naar "CLabelSoort( )"...

Nu is natuurlijk de grote vraag... Waarom gaat hij niet de CLabelSoort (ltInfo) gaan construeren?

BTW curry, heb jij ergens een pagina waarbij ze niet met int/string etc werken, maar met eigen gemaakte classes? Want int & string enz. is eenvoudig, maar wat ik atm nodig heb is dit :S

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Zoek Stroustrup eens op bij P&W FAQ - C/C++ Boeken :)

Die vertelt je ook haarfijn dat in een class-hierarchy iedere afzonderlijke class geconstrueerd moet worden. Indien niet specifiek aangegeven wordt dus van de baseclass de default constructor, dwz. de parameterloze, aangeroepen. Je kunt expliciet een base constructor aangeven dmv deze implementatie:
C++:
1
2
3
4
5
6
CNormaalPakket::CNormaalPakket(const LabelInformation_t &ltInfo)
               :CLabelSoort(ltInfo)
{
// Constructie van CNormaalPakket zelf
...
}

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Waarom maak je uberhaupt private default constructors aan trouwens :?

Professionele website nodig?


Verwijderd

Topicstarter
Omdat ik niet wil dat die labels gemaakt worden zonder gegevens :) je MOET die ltInfo meegeven, anders maggem nix doen :)

Dat heb ik vroeger geleerd op school dat als je niet wil dat mensen uw classes gaan gebruiken zonder iets mee te geven dat je het dan privé moet maken.


En ik zal dadelijk eens kijken naar die boek :)

  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 13:30

BoAC

Memento mori

Verwijderd schreef op 03 november 2003 @ 13:49:
Omdat ik niet wil dat die labels gemaakt worden zonder gegevens :) je MOET die ltInfo meegeven, anders maggem nix doen :)

Dat heb ik vroeger geleerd op school dat als je niet wil dat mensen uw classes gaan gebruiken zonder iets mee te geven dat je het dan privé moet maken.

En ik zal dadelijk eens kijken naar die boek :)
Of gewoon die standaard construtor weglaten ;)

Verwijderd

Topicstarter
Nee, als ik die weglaat, dan begint hij te zagen dat hij die niet vind (in het geval dat ik die ":CLabelSoort(ltInfo)" er niet bij zet dus hé. Anders is het OK voor hem.

Maar als ik die gewoon privé maak weet ik zeker dat er iets verkeerd is (de compiler gaat van zijn oren maken ;))

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

Maar dan kun je CNormaalPakket niet constructen zonder parameters, of je moet een dummy LabelInformation_t meegeven aan de constructor va CLabelSoort. Maak 'm dus protected, of laat 'm idd gewoon in z'n algemeenheid weg

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Je bent nu dus verkeerdom aan het pleisteren. Zodra er geen constructor is, maakt de compiler een default-default constructor aan die niets doet. Dit houdt in dat je het object gewoon mag creeren. Zodra er wel een constructor is moet je verplicht 1 van de gedefinieerde constructors gebruiken, en als die parameters vragen of protected/private zijn heb je je daar dus aan te conformeren.

Dat ie zonder een expliciete base-constructorcall zeikt dat CLabelSoort() private is is 100% correct: het is z'n enige manier om de base class te construeren namelijk. Ergo dit dien je op te lossen door gewoon je constructors goed te definieeren en niet door lelijke pleistermiddelen te gaan gebruiken die je code vervuilen met onzin (private constructors zonder friend-declaratie... lekker nuttig :P )

Geef de docent die je dit heeft aangeleerd maar een harde schop voor z'n genitalieen, als je dit bij een bedrijf uithaalt in productiecode wordt je hard weggelachen :Y)

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zodra er wel een constructor is moet je verplicht 1 van de gedefinieerde constructors gebruiken, en als die parameters vragen of protected/private zijn heb je je daar dus aan te conformeren.
de uitzondering hierop is overigens de copy-constructor, die default gegenereerd wordt als je 'm niet specificeert

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

.oisyn schreef op 03 november 2003 @ 14:47:
[...]
de uitzondering hierop is overigens de copy-constructor, die default gegenereerd wordt als je 'm niet specificeert
Excusez-moi idd, de default-default constructor doet niets en de default-copy constructor doet een bitwise copy :)

* curry684 vergeet ook wel eens wat te vermelden 8)7

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 03 november 2003 @ 14:22:Geef de docent die je dit heeft aangeleerd maar een harde schop voor z'n genitalieen, als je dit bij een bedrijf uithaalt in productiecode wordt je hard weggelachen :Y)
Zallek doen :) Kzit toch nie meer daar op't school dus :p

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 17:14
curry684 schreef op 03 november 2003 @ 14:51:
[...]
Excusez-moi idd, de default-default constructor doet niets en de default-copy constructor doet een bitwise copy :)

* curry684 vergeet ook wel eens wat te vermelden 8)7
Zoals dat de default-copy helemaal geen bitwise copy doet. :X

Default-copy ctor doet namelijk een default-copy voor alle members. Voor built-ins
is dat feitelijk gelijk aan een bitwise copy (alhoewel padding in theorie niet gekopieerd hoeft te worden), maar een std::string member wordt heus niet ge bit-copied.
Om dezelfde reden doet een default ctor dus een default construction van alle class-type members. Voor een std::string member wordt dus netjes de default ctor aangeroepen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 17:14
curry684 schreef op 03 november 2003 @ 14:22:
(private constructors zonder friend-declaratie... lekker nuttig :P )
Best wel. Een typische singleton class heeft dat als kenmerk:
C++:
1
2
3
4
5
6
7
class Singleton {
  private:
    Singleton( );
    Singleton( const& Singleton ); // Not implemented
  public:
    Singleton& instance();
}

De bedoeling is dat je er niet een kunt maken, want dan zou je er ook twee kunnen maken. Het enige wat je kunt doen is een reference krijgen naar het unieke object.

Vergelijkbare patterns heb je met static class factory methods, waar je bijvoorbeeld een heap-object terugkrijgt verpakt in een smart pointer.

[ Voor 2% gewijzigd door MSalters op 03-11-2003 17:51 . Reden: [/code] ]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 17:14
curry684 schreef op 03 november 2003 @ 11:06:
Alles is een class, ook een int, vandaar mijn vraag om dat begrip te kweken ;)

Puur technisch bezien is een int ook een class met constructors, operator overloads en alles erop en eraan. Dus vandaar dat je een willekeurige andere class overal op exact dezelfde manier als een int kunt en moet gebruiken.
Bijna een class. int heeft bijvoorbeeld geen default constructor, maar wel een pseudo-constructor syntax:
int a = int(); // =0, maar
int a; // uninitialized.

Voor een echte class C geldt dat temporary C() en definite C a; allebei hetzelfde resultaat opleveren.

Bovendien kun je bij classes een pointer-to-member creeren, en dat lukt bij ints niet zo. Veel classes gedragen zich als ints, maar andersom is dat niet zo.

En er is nog een heel belangrijk verschil. Ints hebben in-class initialization:

C++:
1
2
3
4
5
6
class C {
  static const int i = 5; // legaal
  static const std::string s = "5"; //illegaal
};
const int C::i;
const std::string C::s;

[ Voor 13% gewijzigd door MSalters op 03-11-2003 17:58 ]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

MSalters schreef op 03 november 2003 @ 17:46:
[...]

Zoals dat de default-copy helemaal geen bitwise copy doet. :X

Default-copy ctor doet namelijk een default-copy voor alle members. Voor built-ins
is dat feitelijk gelijk aan een bitwise copy (alhoewel padding in theorie niet gekopieerd hoeft te worden), maar een std::string member wordt heus niet ge bit-copied.
Om dezelfde reden doet een default ctor dus een default construction van alle class-type members. Voor een std::string member wordt dus netjes de default ctor aangeroepen.
Mwah nu ben je mieren aan het verkrachten :)

Bij default ctor zei ik dat de members niet geinitialiseerd werden. Dat voor een member met een wel gedefinieerde default ctor vervolgens wel die ctor wordt aangeroepen beschouw ik net zo hard als standaard en logisch als dat van een base class altijd de default ctor wordt aangeroepen indien niet expliciet gedefinieerd (wat ook een foute insteek was om voor bekend aan te nemen overigens zoals we hierboven hebben gezien ;) ). Dat voor een default copyctor hetzelfde verhaal geldt is tevens wmb 'implicit knowledge' :)

* curry684 neemt soms teveel aan aan basiskennis bij de 'studenten' :Y)

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

MSalters schreef op 03 november 2003 @ 17:56:
[...]
En er is nog een heel belangrijk verschil. Ints hebben in-class initialization:
C++:
1
2
3
4
5
6
class C {
  static const int i = 5; // legaal
  static const std::string s = "5"; //illegaal
};
const int C::i;
const std::string C::s;
Deze wist ik trouwens niet... dit mag toch alleen omdat ie const is? Anders krijg je toch problemen met internal/external linkage? :?

Professionele website nodig?

Pagina: 1