Undefined reference to Destructor
Solution 1
You need to make sure you compile all of your .cc files together. So do g++ -Wall articles.cc testArticles.cc
, or whatever your files are actually called. This will compile each file into a .o (object) file and link them together for you. You can do this in multiple steps if you want:
g++ -Wall -c articles.cc
g++ -Wall -c testArticles.cc
g++ articles.o testArticles.o
Solution 2
You need to include all source files in your command line arguments:
g++ -Wall testArticles.cc articles.cc
Alternatively, you can create a makefile which defines the dependencies between your sourcefiles. This is a handy tool for C++ programmers, especially in a *nix environment.
Solution 3
You're compiling and linking testArticles.cc
, but you're not compiling articles.cc
. This is why you're getting the linker errors; you're not actually implementing the methods anywhere the compiler can see.
Try using
g++ -Wall articles.cc testArticles.cc
André Hincu
Updated on June 04, 2022Comments
-
André Hincu almost 2 years
I have written some code in c++ but when I try to compile, I get a very strange error that I should not have. Here is my code:
#include <iostream> using namespace std; #include "articles.h" int main() { // Création des articles const Stylo s1 ("s1", "Stylo jade", "Watertruc", 500, "Noir"); const Ramette r1 ("r1", "Ramette haute qualité", "Clairefont", 95, 80); // Création des lots (10 % de réduction) const Lot l1 ("l1", s1, 5, 10); cout << s1 << "\n" << r1 << "\n" << l1 << "\n"; }
articles.h
#ifndef ARTICLES_H #define ARTICLES_H using namespace std; #include <string> #include <iostream> class Article { public: string getReference() const ; virtual string getDescriptif() const; virtual double getPU() const; string getMarque() const; virtual void Afficher(ostream&) const; ~Article(); protected: Article(string); string reference; private: }; //ostream& operator<<(ostream& os, const Article& art); class ArticleUnitaire : public Article { public: ArticleUnitaire(string); ArticleUnitaire(string, string, string, double); string getMarque() const; void setMarque(string&); double getPU() const; void setPU(double&); void setDescriptif(string&); string getDescriptif() const; virtual void Afficher(ostream&) const; ~ArticleUnitaire(); protected: string marque; double pu; string descriptif; private: }; inline ostream& operator<<(ostream& os, const Article& art) { art.Afficher(os); return os; } class Stylo : public ArticleUnitaire { public: Stylo(string, string, string, double, string); virtual void Afficher(ostream&) const; string getCouleur() const; ~Stylo(); protected: private: string couleur; }; class Ramette : public ArticleUnitaire { public: Ramette(string, string, string, double, int); virtual void Afficher(ostream&) const; int getGrammage() const; ~Ramette(); protected: private: int grammage; }; class Lot : public Article { public: Lot(string, Article, int, int); double getPU() const; string getDescriptif() const; string getMarque() const; int getNbArticles() const; void setNbArticles(int&); int getPourcentage() const; void setPourcentage(int&); Article getArticle() const; void setArticle(Article&); virtual void Afficher(ostream&) const; ~Lot(); protected: private: int nb; int pourcentage; Article art; }; #endif // ARTICLES_H
articles.cc
using namespace std; #include <typeinfo> #include <string> #include <sstream> #include "articles.h" /* Article */ Article::Article(string ref) : reference(ref) {}; string Article::getReference() const { return reference; } string Article::getMarque() const { return "Sans marque"; } void Article::Afficher(ostream& os) const { os << " : reference = " << getReference() << " ; descriptif = " << getDescriptif() << " ; marque = " << getMarque() << " ; PU = " << getPU(); } Article::~Article() {}; /* Article Unitaire */ ArticleUnitaire::ArticleUnitaire(string r) : Article(r) {}; ArticleUnitaire::ArticleUnitaire(string r, string d, string m, double p) : Article(r), marque(m), descriptif(d), pu(p) {}; string ArticleUnitaire::getMarque() const { return marque; } void ArticleUnitaire::setMarque(string& m) { marque = m; } double ArticleUnitaire::getPU() const { return pu; } void ArticleUnitaire::setPU(double& p) { pu = p; } void ArticleUnitaire::setDescriptif(string& d) { descriptif = d; } string ArticleUnitaire::getDescriptif() const { return descriptif; } ArticleUnitaire::~ArticleUnitaire() {}; /* Stylo */ Stylo::Stylo(string r, string d, string m, double p, string c) : ArticleUnitaire(r,d,m,p), couleur(c) {}; string Stylo::getCouleur() const { return couleur; } void Stylo::Afficher(ostream& os) const { Article::Afficher(os);Lot os << " ; couleur = " << getCouleur(); } Stylo::~Stylo() {}; /* Ramette */ Ramette::Ramette(string r, string d, string m, double p, int g) : ArticleUnitaire(r,d,m,p), grammage(g) {}; int Ramette::getGrammage() const { return grammage; } void Ramette::Afficher(ostream& os) const { Article::Afficher(os); os << " ; grammage = " << getGrammage(); } Ramette::~Ramette() {}; /* Lot */ Lot::Lot(string r, Article a, int n, int p) : Article(r), art(a), nb(n), pourcentage(p) {}; double Lot::getPU() const { return nb * art.getPU() * (100 - pourcentage) / 100; } string Lot::getDescriptif() const { stringstream sstm; sstm << "Lot de" << nb << " *" << art.getDescriptif() << "* "; return sstm.str(); } string Lot::getMarque() const { return art.getMarque(); } int Lot::getNbArticles() const { return nb; } void Lot::setNbArticles(int& nbArticles) { nb = nbArticles; } int Lot::getPourcentage() const { return pourcentage; } void Lot::setPourcentage(int& p) { pourcentage = p; } Article Lot::getArticle() const { return art; } void Lot::setArticle(Article& a) { art = a; } void Lot::Afficher(ostream& os) const { Article::Afficher(os); os << " ;reduction = " << getPourcentage() << " ; compose de " << getNbArticles() << " [" << art << " ]"; } Lot::~Lot() {};
when I compile:
g++ -Wall testArticles.cc /tmp/ccwWjTWv.o: In function `main': testArticles.cc:(.text+0xe8): undefined reference to `Stylo::Stylo(std::string, std::string, std::string, double, std::string)' testArticles.cc:(.text+0x218): undefined reference to `Ramette::Ramette(std::string, std::string, std::string, double, int)' testArticles.cc:(.text+0x2da): undefined reference to `Lot::Lot(std::string, Article, int, int)' testArticles.cc:(.text+0x307): undefined reference to `Article::~Article()' testArticles.cc:(.text+0x36f): undefined reference to `Lot::~Lot()' testArticles.cc:(.text+0x37b): undefined reference to `Ramette::~Ramette()' testArticles.cc:(.text+0x387): undefined reference to `Stylo::~Stylo()' testArticles.cc:(.text+0x3b4): undefined reference to `Stylo::~Stylo()' testArticles.cc:(.text+0x3e8): undefined reference to `Stylo::~Stylo()' testArticles.cc:(.text+0x41c): undefined reference to `Stylo::~Stylo()' testArticles.cc:(.text+0x450): undefined reference to `Stylo::~Stylo()' testArticles.cc:(.text+0x48c): undefined reference to `Ramette::~Ramette()' testArticles.cc:(.text+0x4c0): undefined reference to `Ramette::~Ramette()' testArticles.cc:(.text+0x4f4): undefined reference to `Ramette::~Ramette()' testArticles.cc:(.text+0x533): undefined reference to `Lot::~Lot()' testArticles.cc:(.text+0x556): undefined reference to `Article::~Article()' testArticles.cc:(.text+0x56a): undefined reference to `Lot::~Lot()' testArticles.cc:(.text+0x57e): undefined reference to `Lot::~Lot()' testArticles.cc:(.text+0x58f): undefined reference to `Ramette::~Ramette()' testArticles.cc:(.text+0x5a0): undefined reference to `Stylo::~Stylo()' /tmp/ccwWjTWv.o: In function `Article::Article(Article const&)': testArticles.cc:(.text._ZN7ArticleC2ERKS_[_ZN7ArticleC5ERKS_]+0x17): undefined reference to `vtable for Article' collect2: error: ld returned 1 exit status
I went online on every possible website, and everybody says the same thing: it looks like I messed up the #include(s). But I have been very carefull, I am sure that it is about something stupid and minor, but it's been 6 hours and I am starting to give up. It is very weird.