Erreur "undefined reference"

Aquarigio_116 Messages postés 1 Statut Membre -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour à tous !

Dans le cadre de mon projet de BTS je dois faire un code pour effectuer entre autre une requête à une base de données. Je rencontre un problème dans mon main quand je veux créer un objet de ma classe BDD, j'ai beau chercher je ne comprend pas.

L'erreur renvoyée est
undefined reference to 'BDD::~BDD()
. J'ai déjà regardé des tutoriels mais même en appliquant ce qu'ils disent l'erreur persiste.

Je vous mets tout ça en image et en code pour mieux comprendre.

Merci d'avance pour vous être intéressé à mon cas !!

PS : J'ai enlevé tout une partie dans mon main qui n'est pas intéressante pour mon problème, donc ne faites pas attention à tout ce qui concerne la couleur, le TSL ou autre et qui n'a aucun rapport avec le sujet :)

main.cpp :

#include "BDD.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <math.h>


using namespace std;


int main()
{

    BDD bdd;

/*
    //Quand ma création d'objet fonctionnera j'espère pouvoir faire fonctionner ces 2 lignes
    vector<Couleur*> DonneesRecues = bdd.requeteCouleur();
    int taille = DonneesRecues.size();


*/}


BDD.h :

#include <string>
#include <vector>
#include <winsock.h>
#include <MYSQL/mysql.h>

using std::string;
using std::vector;
struct Couleur;


#pragma once

class BDD
{
private:
 MYSQL mysql;

public:
 BDD();
 vector<Couleur*> requeteCouleur();
 ~BDD();
};

struct Couleur
{
 int T, S, L;

 string refPeinture, fournisseur;

 Couleur(char* T, char* S, char* L, char* refPeinture, char* fournisseur)
 {
  this->T = atoi(T);
  this->S = atoi(S);
  this->L = atoi(L);
  this->refPeinture = refPeinture;
  this->fournisseur = fournisseur;
 }

 ~Couleur()
 {
 }

};


BDD.cpp :

#include "BDD.h"


BDD::BDD()
{
 mysql_init(&mysql);
 mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "");
}

vector<Couleur*> BDD::requeteCouleur()
{
 vector<Couleur*> res;

 if (mysql_real_connect(&mysql, "172.16.8.84", "visiteur", "1234", "peinture", 0, NULL, 0))
 {

        mysql_query(&mysql, "SELECT T_Couleur, S_Couleur, L_Couleur, Reference_Produit_Couleur, Fournisseur_Couleur FROM Couleur");
        MYSQL_RES *resultatSQL = NULL;
        MYSQL_ROW row;
        resultatSQL = mysql_use_result(&mysql);
        while ((row = mysql_fetch_row(resultatSQL)))
        {
            unsigned long *lengths;
            lengths = mysql_fetch_lengths(resultatSQL);
            res.push_back(new Couleur((char*)row[0] ? row[0] : "0", (char*)row[1] ? row[1] : "0", (char*)row[2] ? row[2] : "0", (char*)row[3] ? row[3] : "0", (char*)row[4] ? row[4] : "0"));
        }
        mysql_close(&mysql);
  cout << "La connexion a terminee" << endl;
 }
 else
 {
  cout << "Une erreur s'est produite lors de la connexion a la base de donnees" << endl;
 }
 return res;
}

BDD::~BDD()
{

}


L'erreur en question :

1 réponse

  1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    Bonjour,

    Plusieurs recommandations : Indente ton code, et rends le minimal (cf ta discussion sur color) avant de poser ta question.

    Pré-requis

    Tout d'abord quelques rappels sur la compilation en C++ quand plusieurs fichiers sont mis en jeu.

    1) Le pré-compilateur résout toutes les opérations précédées de
    #
    (précompilation), ce qui inclue notamment
    #include
    et
    #define
    . Il n'y a pas d'intelligence à ce stade ce ne sont que des manipulation texte (copier-coller, substitution, etc). Si un
    #include
    n'est pas résolu, c'est soit que le chemin est faux, soit qu'il faut passer des options au compilateur pour lui dire où chercher. Ce n'est pas ton erreur ici.

    2) Le compilateur (e.g.
    g++
    ) compile individuellement chaque fichier source (fichiers
    .cpp
    ). À ce stade les fonctions déclarées mais non implémentées (comme celles récupérées par inclusion d'un header) ne lève pas d'erreur. C'est le travail du linker (voir étape 3). Donc à ce stade, le compilateur s'occupe de générer le code machine correspondant aux fonctions implémentées dans le
    .cpp
    et suppose que le reste sera retrouvé par la suite. Chaque fichier
    .cpp
    engendre un fichier
    .o
    . Si une méthode / fonction n'est pas trouvée parmi les fonctions déclarée tu auras une erreur.

    3) Le linker s'occupe de rassembler les "morceaux" pour former le binaire final. Ce binaire final peut être la l'exécutable (
    .exe
    sous windows) ou la librairie (
    .dll
    ou
    .lib
    sous windows ;
    .so
    ou
    .a
    sous linux) que tu es en train de compiler. En outre le linker vérifie que chaque fonction utilisée est implémentée exactement une seule fois à partir des "morceaux" qu'on réunit. Et donc naturellement les erreurs typiques à cette étape sont des définitions multiples (plus d'une occurrence) ou non résolues (aucune occurrence trouvée). Les "morceaux" réunis sont typiquement des
    .o
    ou des librairies.

    Retour à ton problème

    Dans ton cas, tu as un problème lié au linkage. Voici un exemple complet, fonctionnel, et minimal :

    bdd.hpp :

    #ifndef BDD_HPP
    #define BDD_HPP
    
    class Bdd {
    public:
        Bdd();
        ~Bdd();
    };
    
    #endif


    bdd.cpp :

    #include <iostream>
    #include "bdd.hpp"
    
    using namespace std;
    
    Bdd::Bdd() {
        cout << "construction" << endl;
    }
    
    Bdd::~Bdd() {
        cout << "destruction" << endl;
    }


    main.cpp :

    #include "bdd.hpp"
    
    int main() {
        Bdd * bdd = new Bdd();
        delete bdd;
        return 0;
    }


    Compilation :

    (Ici sous linux) :

    g++ -c bdd.cpp
    g++ -c main.cpp
    g++ main.o bdd.o -o programme


    Les deux premières commandes produisent respectivement
    bdd.o
    et
    main.o
    . La troisième commande réunit
    main.o
    ,
    bdd.o
    pour produire l'exécutable
    programme
    (qu'on appelerait
    programme.exe
    sous windows). On aurait typiquement écrit quelque chose du genre
    g++ main.o bdd.o -lmysql -o programme
    pour linker avec
    /usr/lib/libmysql.so
    .

    Exécution :

    (mando@silk) (~) $ ./programme
    construction
    destruction


    Bonne chance
    0