Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C++] Inheritance: undefined symbol bij nieuwe class

Pagina: 1
Acties:

  • The__Virus
  • Registratie: Januari 2005
  • Laatst online: 27-11 09:56
Ik heb een vreemd probleem, waar ik niets van snap.

Ik heb een bestand.h met daarin 2 classes, stel A en B. Nu wil ik een derde class maken die erft van A en een vierde die erft van B.

dus mijn code is:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A;
class C;
class D;
class B
{
public:
bla bla
private:
bla bla
}

class A
{
public:
bla bla
private:
bla bla
}

Tot aan hier werkt het. Dan komt de eerste nieuwe class:
C++:
1
2
3
4
5
6
7
class C : public A
{
public:
bla bla
private:
bla bla
}

Ik maakte eerst een nieuw object aan met
C++:
1
2
3
A a;
a.insert(bla)
a.remove(bla)

Maar zodra ik nu al zeg C c; dan geeft ie de error dat C een undefined symbol is en alle functies die beginnen met c. herkent ie niet (wat dan ook logisch is).
Ook kan ik geen functies definiëren op de manier zoals ik dat hierboven deed, de constructor en destructor moeten in de class zelf staan en kunnen niet zo worden gebruikt bijv:
C::C
{
}
C::~C
{
}

Want ook dat geeft een foutmelding: Qualifier C is not a class or namespace name

In Borland staat C keurig onder de classes maar toch wordt deze niet herkend. De plek waar ik de class verder definieer (de constructor/destructor en functies) maakt niets uit, onder of boven, het wordt niet herkend. Dit lijkt mij te komen omdat er : public A staat, maar ik snap echt totaal niet waarom dit niet werkt. In al mijn voorbeelden staat het zo en zou het moeten werken...

class A moet sowieso bovenaan, omdat B een verwijzing heeft naar A (zit een element in dat aangeeft in welke A object B zit).

Ik heb eerder gehad dat het niet werkte en maakte toen gewoon het project opnieuw. Probleem is dat ik dit al drie keer heb gedaan en nog steeds blijf ik deze foutmelding krijgen.

Ik heb A en B reeds eerder gemaakt en in een bestand.h gezet en deze samen met de rest van de code gekopieerd en hiernoemd. Hierna werkt het nog steeds, maar zodra ik ervende classes ga toevoegen, gaat het fout.

edit:
Het gaat dus ook fout bij niet ervende classes. Volgens mij zit ik óf weer op de onverklaarbare fout die ik eerder ook had (alleen kan hem niet oplossen) óf er zit echt iets fout in mijn code.

[ Voor 29% gewijzigd door The__Virus op 06-11-2007 13:50 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je geeft niet de cruciale info, namelijk de layout van je headerfiles en hoe je die include in je sourcefile. Je zegt wel dat bestand.h 2 classes heeft (A en B), waar leeft C dan? En include je die wel in de sourcefiles waarin je C wilt gebruiken?

Overigens sluit je je classes in je voorbeeld niet af met een accolade (;), maar ik gok dat je dat gewoon even snel had ingetypt hier :)

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.


  • The__Virus
  • Registratie: Januari 2005
  • Laatst online: 27-11 09:56
Die accolade doe ik idd wel, vergeten ;)

Ik zet ze in hetzelfde bestand als de vorige classes.

Maar het wordt allemaal nog gekker. Als ik in zowel de .cpp (waarin de functies staan) als in de header als in de .cpp waarin de main staat, alle keren A vervang door X (dus ik verander de naam) dan pakt ie het niet en geeft ie weer aan 'undefined symbol' en 'Qualifier X is not a class or namespace name'. Het lijkt erop dat óf ergens iets van verborgen tekst is waar het programma de namen nog eens vastlegt ofzo óf dat er een bug in Borland zit, ik wordt echt helemaal gek!

edit:
Nog een keer geprobeerd, in de drie bestanden (2x .cpp, 1x .h) alle termen A vervangen door X en hij geeft gewoon die errors. Dat slaat toch nergens op?! Ik kan je evt. de sourcecode wel geven van het geheel, misschien dat je er iets mee kunt:

bestand.cpp:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include "dlist.h"

void main()
{
    DList my_list;

    char command;
    printf("-------- Ring-style linked list base class --------\n\n");
    do
    {
        printf("Type command: ");
        fflush(stdin);
        scanf(" %c", &command);
        switch (command)
        {
            default :
                printf("Command unknown!\n");
                break;
        }
    }
    while (command != 'q');

    my_list.destroy_list();

    printf("Bye bye!\n");
}

dlist.h:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class DList;



class Item
{
public:
    Item();
    ~Item();

    virtual void print(void);

private:
    Item * _prev;
    Item * _next;
    int _id;
    DList * _dlist;
    friend class DList;
};

class DList
{
public:
    DList();
    ~DList();
    void remove(Item * old_item);
    virtual void print(void);
    void append(void);
    int Delete(int id);
    void destroy_list(void);
    void insert(void);
    int put_first(int id);
    void sort(void);
private:
    Item * _top_of_ring;
};

dlist.cpp:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <stdio.h>
#include "dlist.h"

Item::Item()
{
    static int id=0;
    id+=1;
    _id=id;
}

Item::~Item()
{
    _dlist->remove(this);
}

void Item::print()
{
    printf("item id %d\n",_id);
}

DList::DList()
{
    _top_of_ring = 0;
}

DList::~DList()
{
   destroy_list();
}

void DList::print(void)
{
        if(_top_of_ring)
        {
                functie
        }
        else
        {
                printf("-> List contains no items\n");
        }
}

void DList::remove(Item * old_item)
{
        old_item->_dlist = 0;
        old_item->_prev->_next = old_item->_next;
        old_item->_next->_prev = old_item->_prev;
        if(old_item == _top_of_ring)
        {
                functie
        }
        return;
}

void DList::append(void)
{
        Item * new_item = new Item;
        if(_top_of_ring)
        {
                functie
        }
        else
        {
                functie
        }
        new_item->_dlist = this;
        printf("-> Appended ");
        new_item->print();
}

int DList::Delete(int id)
{
        if(_top_of_ring)
        {
                Item * current_item = _top_of_ring;
                Item * last_item = _top_of_ring->_prev;
                for(current_item; current_item != last_item; current_item = current_item->_next)
                {
                        functie
                }
                if(last_item->_id == id)
                {
                        functie
                }
                return 0;
        }
        printf("-> List contains no items\n");
        return -1;
}

void DList::destroy_list(void)
{
        if(_top_of_ring)
        {
                functie
        }
        printf("-> List contains no items\n");
        return;
}

void DList::insert(void)
{
        Item * new_item = new Item;
        if(_top_of_ring)
        {
                functie
        }
        else
        {
                functie
        }
        new_item->_dlist = this;
        printf("-> Inserted ");
        new_item->print();
}

int DList::put_first(int id)
{
        if(_top_of_ring)
        {
                functie
                return id;
        }
        printf("-> List contains no items\n");
        return -1;
}

void DList::sort(void)
{
        if(_top_of_ring)
        {
                functie
        }
        else
        {
                printf("-> List contains no items\n");
        }
}


Zo werkt het nog (alleen functie moet je ff weghalen ofzo, dan zal het ook wel werken). Zodra ik hier dan alles van DList verander in Book, werkt het niet meer.

[ Voor 80% gewijzigd door The__Virus op 06-11-2007 14:26 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dus als je deze file compileert dan krijg je errors?
C++:
1
2
3
4
5
6
7
8
9
10
11
12
struct A { };
struct B { };
struct C : A { };
struct D : B { };

int main()
{
    A a;
    B b;
    C c;
    D d;
}


Zit je niet toevallig ook nog eens met namespaces te kloten? Oftewel, post je hele code eens, gereduceerd tot het minimale wat nog wel de error geeft :)

[ Voor 28% gewijzigd door .oisyn op 06-11-2007 14:17 ]

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.


  • The__Virus
  • Registratie: Januari 2005
  • Laatst online: 27-11 09:56
Jouw code doet het wel, maar dat werkt dan ook met structs. Hoop dat je iets met mijn code hierboven kan. Die hierboven werkt dus, maar zodra ik DList verander geeft al ie een fout. En zodra ik classes toevoeg ook, en zodra die erven ook :P.

Zodra je met de muis over DList gaat, geeft ie ook aan in welk bestand ie zit. Bij Book doet ie dat dan ook (als ik deze als class Book : public DList toevoeg), maar dan verschijnt er niets. Je ziet dus dat ie wat probeert (even een zandlopertje) en vervolgens komt er niets.

[ Voor 76% gewijzigd door The__Virus op 06-11-2007 14:33 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

naar X dus oid?

En classes/structs maakt natuurlijk geen zak uit, het zijn dezelfde dingen :)

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.


  • The__Virus
  • Registratie: Januari 2005
  • Laatst online: 27-11 09:56
Ja verander elke DList maar eens in Book, in alle bestanden. Dan werkt het nog niet, undefined symbol. En als ik in dlist.h dus een class toevoeg, maakt niet uit hoe (met of zonder erven) en in dlist.cpp de functie aanroep, geeft ie aan dat ie niet bestaat ook al zie ik hem links in het rijtje met classes staan.

Minder fijn programma :(

[ Voor 54% gewijzigd door The__Virus op 06-11-2007 14:36 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hmm... ik gok iets met precompiled headers oid. Als je het verandert, doe dan eens een full rebuild. En als dat niet werkt, controleer of de headerfile die je zit te editten ook daadwerkelijk de headerfile is die geinclude wordt door je sourcefiles (heb je nog ergens een kopie rondslingeren oid?)

[ Voor 49% gewijzigd door .oisyn op 06-11-2007 14:38 ]

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.


  • The__Virus
  • Registratie: Januari 2005
  • Laatst online: 27-11 09:56
Heb al een aantal keer programma gesloten en opnieuw opgestart en nieuw project gemaakt met de bestanden erin. Als ik een build doe, krijg ik nu een warning dat de header incomplete is...


Krijg nu, na het rebuilden van de source en deze aan te passen, al weer een iets andere (betere?) error:
Heb book nu toevoegd en krijg, als ik deze boven DList, de fout dat DList eerst gedeclareerd moet worden. So far so good, dus ik zet hem eronder. Doe ik dat, dan krijg een linker error met Book::Book() en Book::~Book(), waarschijnlijk omdat deze leeg zijn, maar dat zou toch gewoon mogen. Anyway, als ik ze weghaal dan werkt het dus, niet helemaal zoals het hoort en onbegrijpelijk waarom het niet werkte, maar het werkt... Zou alleen nog willen dat ik Book() en ~Book() gewoon in de class kon opnemen, aangezien dat officieel de opdracht is.

edit:
als ik deze gewoon opneem in de cpp als Book::Book(){} en Book::~Book(){} dan werkt het. Ik zou graag nog een kleine uitleg willen waarom (is het de rebuild all?) en voor de rest _/-\o_

[ Voor 75% gewijzigd door The__Virus op 06-11-2007 14:53 ]


Verwijderd

hij gebruikte de hele tijd waarschijnlijk een header die hij eenmaal gecompileerd heeft en daarna niet meer naar gekeken is door de compiler.

bij overerving wil hij erg graag dat je even een contructor en destructor bakt, dus dat verklaart die laatste fout

edit: zorg in borland dat je header onderdeel is van je project. dan hoort hij opzich te controleren of je header veranderd is en die opnieuw te bakken.

[ Voor 23% gewijzigd door Verwijderd op 06-11-2007 20:23 ]


  • blackangel
  • Registratie: April 2002
  • Laatst online: 27-11 13:21
Verwijderd schreef op dinsdag 06 november 2007 @ 19:51:
hij gebruikte de hele tijd waarschijnlijk een header die hij eenmaal gecompileerd heeft en daarna niet meer naar gekeken is door de compiler.
Dat is de meest waarschijnlijke verklaring inderdaad. In borland moet je Project->Options->Compiler->"Pre-compiled headers" op none zetten als je van dit probleem af wilt komen. (Default: "Cache Pre-compiled headers").

Niet dat ik er vaak last van heb, meestal doe ik eerst een compile unit om zeker te weten dat daar alvast geen domme fouten tussen staan, en dan wordt de headerfile standaard al meegepakt.
bij overerving wil hij erg graag dat je even een contructor en destructor bakt, dus dat verklaart die laatste fout
Zojuist een nutteloos voorbeeldje geschreven, maar het compiled wel gewoon :)
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class a {
    public:
        int var;
};

class b : public a {

};

int main(int argc, char* argv[])
{
    b que;
    que.var = 3;
}


Constructors zijn niet nodig als je geen variabelen bij de constructie wil setten, of eventueel andere classes/geheugen hoeft te declareren. Hetzelfde geld voor destructors, als je geen geheugen hoeft te verwijderen kun je hem net zo goed weg laten. Niet dat het zoveel moeite is om b::b() : a(0) { } en b::~b() { } te doen, maar het is niet verplicht :)

Waar het anders aan kan liggen weet ik niet overigens.


offtopic:
The_Virus, moeten jullie headerfiles gaan aanmaken dan? Of uberhaupt overerving gebruiken? Dat hoefde bij mij 2 jaar geleden nog niet hoor :P

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waar het om gaat is dat als je een non-trivial ctor/dtor declareert, dat je deze dan ook moet implementeren!

Overigens: Borland C++ zuigt enorm, gebruik een fatsoenlijke IDE zoals Visual C++ 2005 (de Express editie is gratis)

[ Voor 35% gewijzigd door .oisyn op 06-11-2007 20:47 ]

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.


  • blackangel
  • Registratie: April 2002
  • Laatst online: 27-11 13:21
Als iets wel gedeclareerd is, maar niet geimplementeerd geeft Borland daar een linkererror op, geen normale compile-error. Al hoewel dat dan weer samen zou kunnen vallen met het precompiled header crap dat er alleen een compile-error op wordt gegeven. :)

offtopic:
Borland is niet heilig, maar VCpp begrijp ik nog minder. Doordat ik nu vanwege m'n studies al ruim een jaar ervaring heb met Borland, hou ik mij bij test/homeprutsels ook wel bij Borland.

En The__Virus "moet" volgens mij ook Borland gebruiken voor zijn studie. Soms heb je niet echt een keuze :)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Krijgt ie toch ook
Doe ik dat, dan krijg een linker error met Book::Book() en Book::~Book(), waarschijnlijk omdat deze leeg zijn
En over de compiler, tja, hij vroeg me nou eenmaal via DM wat voor compiler ik gebruikte en hoe hij die ook kon gebruiken. Maar goed, dat wist jij natuurlijk niet :) (itt de linker error :P).

[ Voor 104% gewijzigd door .oisyn op 06-11-2007 22:55 ]

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.

Pagina: 1