[C++] linker error undefined reference to

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 04-04 16:53
Ik ben bezig met een practicum opdracht voor school en daarvoor heb ik een stukje C++ geschreven. Wanneer ik het project probeer te compilen krijg ik de volgende foutmelding:

[Linker error] undefined reference to 'Creditcard::Creditcard(char const*, int, double)'

Ik heb wat research op internet gedaan maar kom er zelf niet uit, ik heb al geprobeerd alle files te rebuilden met de "Rebuild All" functie van Dev-C++. Waarschijnlijk is het een heel klein probleempje maar op gebied van C++ ben ik echt nog een leek, wie kan mij een zetje in de goede richting helpen?

Hieronder de bestanden:

Creditcard.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
#ifndef CLOCK_H
#define CLOCK_H

class Creditcard {
public:
    // Constructors
    Creditcard(const char nm[], int id, double cred);
    
    // Copy constructor
    Creditcard(const Creditcard & c);
    
    // Destructor
    ~Creditcard(void);
    
    // Public operations
    void print(void);
    double getCredit(void);
    void pay(double am);
    void load(double am);

private:
    char* name;
    int id;
    double credit;
};

#endif


Creditcard.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
#include <iostream>
#include <iomanip>
#include "Creditcard.h"

using namespace std;
////////////////////////////////////////////////////////
// Three parameter constructor
//
Creditcard::Creditcard(const char nm[], int id, double cred) : 
    id(id), credit(cred)
{
    cout << "Calling constructor for Creditcard" << endl;
    
    name = new char [strlen (nm) + 1];
    strcpy (name, nm);        
}

// Copy constructor
//
Creditcard::Creditcard(const Creditcard & c) : 
    id(c.id), credit(c.credit)
{
    cout << "Calling copy-constructor for Creditcard" << endl;
    
    name = new char [strlen (c.name) + 1];
    strcpy(name, c.name);        
}

// Destructor
//
Creditcard::~Creditcard(void)
{
    cout << "Calling destructor for Creditcard" << endl;
    delete [] name;
}
    
void Creditcard::print(void) 
{
    cout << "name " << name; 
    cout << "id " << id;
    cout << "credit " << credit;
}

double Creditcard::getCredit(void) 
{
    return credit;
}

void Creditcard::pay(double am) 
{
    credit = credit - am;
}

void Creditcard::load(double am)
{
    credit = credit + am;
}


CreditcardApp.cpp
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include "Creditcard.h"

using namespace std;

int main(void)
{
    //Create a Creditcard object with operator new:
    Creditcard * pCreditcard = new Creditcard ("Maarten", 1, 10.00);
    
    
    return 0;
}

Acties:
  • 0 Henk 'm!

  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 20-09 23:24

BoAC

Memento mori

Je gegeven string "Maarten" wordt vertaald naar een const char * ipv de const char array die je verwacht ;)

Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 19-09 10:19
Om het nog even iets duidelijker te maken. De linker zoekt de constructor voor creditcard die een const char * als eerste argument accepteert. Deze bestaat helaas niet. Alleen de constructor die als eerste argument const char [] accepteert is er, en dat is helaas niet het zelfde.

De signature van de constructor die de linker verwacht bestaat dus niet.

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 04-04 16:53
Ah, op die manier bedankt. Maar hoe maak ik van "Maarten" en const char array? Moet ik die casten of een afsluitteken toevoegen als '/0' ?

Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
gebruik const std::string& ipv je char* of array dat maakt he makkelijker, als je een char[] of char* meegeeft moet je eigenlijk ook de lengte meegeven. Een array in C++ kent zijn eigen lengte niet en er is geen functie die het je kan vertelen. Een char* of char[] hoeft namelijk niet een zero te bevatten aan het einde en dan werkt strlen ook niet meer om de lengte van je string te bepallen.

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


Acties:
  • 0 Henk 'm!

Verwijderd

Je vergeet tevens in je main() je pCreditcard te deleten na gebruik.

Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 04-04 16:53
NC83 schreef op dinsdag 06 september 2011 @ 19:06:
gebruik const std::string& ipv je char* of array dat maakt he makkelijker, als je een char[] of char* meegeeft moet je eigenlijk ook de lengte meegeven. Een array in C++ kent zijn eigen lengte niet en er is geen functie die het je kan vertelen. Een char* of char[] hoeft namelijk niet een zero te bevatten aan het einde en dan werkt strlen ook niet meer om de lengte van je string te bepallen.
Bedankt voor de tip, maar voor deze practicum opdracht mag ik niet teveel afwijken van de opdracht. Ik zal het dus toch met een char array moeten oplossen. Heb je daar misschien ook een tip voor?

Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 04-04 16:53
Verwijderd schreef op dinsdag 06 september 2011 @ 19:08:
Je vergeet tevens in je main() je pCreditcard te deleten na gebruik.
De CreditcardApp was slechts een test, hieronder de volledige waar de pCreditcard wel verwijderd wordt:

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
#include <iostream>
#include "Creditcard.h"

using namespace std;

int main(void)
{
    //Create a Creditcard object with operator new:
    Creditcard * pCreditcard = new Creditcard ("Maarten", 1, 10.00);
    
    // Use the copy-constructor:
    Creditcard copy (*pCreditcard);
    copy.load (100);

    // Again, use the copy-constructor:
    Creditcard copyTwo = copy;
    copyTwo.load (50);

    // Show some information:
    pCreditcard->print();
    cout << "Creditcard is loaded with 100 euro, so it becomes\n";
    copyTwo.print();
    cout << "Creditcard is loaded with another 50 euro, so it becomes\n";
    copyTwo.print();

    // Destruct the Creditcard object created with operator new:
    delete pCreditcard;

    // Construct some other Creditcard object:
    Creditcard creditcard = Creditcard("Piet", 2, 5.00);
    creditcard.print();    
    
    return 0;
}

Acties:
  • 0 Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
Maarten Kroon schreef op dinsdag 06 september 2011 @ 19:44:
[...]


Bedankt voor de tip, maar voor deze practicum opdracht mag ik niet teveel afwijken van de opdracht. Ik zal het dus toch met een char array moeten oplossen. Heb je daar misschien ook een tip voor?
Dat wordt dan zoiets:
code:
1
2
    char strMaarten[] = { "Maarten" };
    Creditcard * pCreditcard = new Creditcard ( strMaarten, 1, 10.00);

Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 04-04 16:53
Het probleem is opgelost. Alle bestanden moesten onderdeel zijn van 1 project ipv. gewoon in dezelfde map te staan. Hartelijk bedankt voor alle hulp nog.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

BoAC schreef op dinsdag 06 september 2011 @ 17:27:
Je gegeven string "Maarten" wordt vertaald naar een const char * ipv de const char array die je verwacht ;)
roy-t schreef op dinsdag 06 september 2011 @ 17:33:
Om het nog even iets duidelijker te maken. De linker zoekt de constructor voor creditcard die een const char * als eerste argument accepteert. Deze bestaat helaas niet. Alleen de constructor die als eerste argument const char [] accepteert is er, en dat is helaas niet het zelfde.
Jullie praten onzin. In het geval van een functie-argument is een T[] weldegelijk hetzelfde als een T*. En áls het niet hetzelfde zou zijn zou je nog altijd een compile error krijgen, geen link error.
NC83 schreef op dinsdag 06 september 2011 @ 19:06:
als je een char[] of char* meegeeft moet je eigenlijk ook de lengte meegeven.
Nonsens natuurlijk, je kunt gewoon in je precondities documenteren dat het een zero-terminated string moet zijn. En dat zijn C-style strings en literals automatisch, dus ik zie het probleem niet echt. Ik wil niet zeggen dat een std::string niet mooier is, maar feit blijft dat je niet per se de lengte hoeft mee te geven.

[ Voor 24% gewijzigd door .oisyn op 06-09-2011 23:49 ]

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