Multiple inheritance and error "Undefined reference to…"

I have in my task 4 classes:
a) Person (abstract class with one pure virtual method show and pure virtual destructor)
b) Gunslinger (inherits virtual from Person)
c) PokerPlayer (inherits virtual from Person)
d) BadDude (inherits from both Gunslinger and PokerPlayer classes)

Code of all classes:
Person.h

#ifndef PERSON_H_
#define PERSON_H_

#include <string>
#include <iostream>

class Person
{
    private:
        std::string name;
        std::string surname;
    public:
        Person(std::string m_name = "Unknown", std::string m_surname = "Unknown") : name(m_name), surname(m_surname) {}
        virtual void show() const = 0;
        virtual void set();
        virtual ~Person() = 0;

};

#endif PERSON_H_

person.cpp

#include "person.h"

void Person::show() const
{
    std::cout << "Name: " << this->name << ". Surname: " << this->surname << std::endl;
}

void Person::set() 
{
    std::cout << "Write name of person: ";
    std::getline(std::cin, this->name);
    std::cout << "Write surname of person: ";
    std::getline(std::cin, this->surname);
}

Person::~Person() {}

gunslinger.h

#ifndef GUNSLINGER_H_
#define GUNSLINGER_H_

#include "person.h"

class Gunslinger: public virtual Person
{
    private:
        int gushesOnRevolver;
    protected:
        double timeOfDrawing;
    public:
        Gunslinger(int m_gushesOnRevolver = 0, double m_timeOfDrawing = 0.0, std::string name = "Unknown", std::string surname = "Unknown");
        int getGushesOnRevolver() { return this->gushesOnRevolver;}
        virtual void show() const override;
        virtual void set() override;
};

#endif GUNSLINGER_H_

gunslinger.cpp

#include "gunslinger.h"

Gunslinger::Gunslinger(int m_gushesOnRevolver, double m_timeOfDrawing, std::string name, std::string surname) : Person(name, surname)
{
    if(m_gushesOnRevolver < 0)
        this->gushesOnRevolver = 0;
    else
        this->gushesOnRevolver = m_gushesOnRevolver;
    if(m_timeOfDrawing < 0)
        this->timeOfDrawing = 0;
    else
        this->timeOfDrawing = m_timeOfDrawing;
}

void Gunslinger::set()
{
    Person::set();

    std::cout << "Write number of gushes on the revolver: ";
    int temp;
    while(!(std::cin >> temp))
    {
        std::cin.clear();
        std::cin.ignore();
        std::cout << "Try again writing number of gusher on the revolver: ";
    }
    this->gushesOnRevolver = temp;

    std::cout << "Write time of drawing the revolver by gunslinger: ";
    while(!(std::cin >> temp))
    {
        std::cin.clear();
        std::cin.ignore();
        std::cout << "Try again writing time of drawing the revolver: ";
    }
    this->timeOfDrawing = temp;
}

void Gunslinger::show() const
{
    Person::show();
    std::cout << "Gushes on revolver: " << this->gushesOnRevolver << ".nTime of drawing it by gunslinger: " << this->timeOfDrawing << std::endl;
}

poker_player.h

#ifndef POKER_PLAYER_H_
#define POKER_PLAYER_H_

#include "person.h"

class PokerPlayer: public virtual Person
{
    private:
        int randomCardNum;
    public:
        PokerPlayer(std::string =  "Unknown", std::string = "Unknown");
        void show() const override;
};


#endif POKER_PLAYER_H_

poker_player.cpp

#include "poker_player.h"
#include <chrono>
#include <random>

PokerPlayer::PokerPlayer(std::string name, std::string surname) : Person(name, surname)
{
    std::random_device rd;
    std::mt19937::result_type seed = rd() ^ (
            (std::mt19937::result_type)
            std::chrono::duration_cast<std::chrono::seconds>(
                std::chrono::system_clock::now().time_since_epoch()
                ).count() +
            (std::mt19937::result_type)
            std::chrono::duration_cast<std::chrono::microseconds>(
                std::chrono::high_resolution_clock::now().time_since_epoch()
                ).count() );

    std::mt19937 gen(seed);
    std::uniform_int_distribution<int> distrib(1,52);
    this->randomCardNum = distrib(gen);
}

void PokerPlayer::show() const
{
    
}

bad_dude.h

#ifndef BAD_DUDE_H_
#define BAD_DUDE_H_

#include "gunslinger.h"
#include "poker_player.h"

class BadDude : public Gunslinger, public PokerPlayer
{
    public:
        BadDude(int gushesOnRev = 0, double timeOfDraw = 0.0, std::string name = "Unknown", std::string surname = "Unknown");
        int getDrawTimeOfRev() const { return this->timeOfDrawing; }
        int getCardOfPlayer() const { return this->getCardOfPlayer(); }
        void show() const override;
        void set() override;
};

#endif BAD_DUDE_H_

bad_dude.cpp

#include "bad_dude.h"

BadDude::BadDude(int gushesOnRev, double timeOfDraw, std::string name, std::string surname) 
    : Person(name, surname), Gunslinger(gushesOnRev, timeOfDraw, name, surname), PokerPlayer(name, surname)
{

}

void BadDude::show() const
{
    Gunslinger::show();
    std::cout << "Time of drawing his revolver: " <<  this->getDrawTimeOfRev() << std::endl;
    std::cout << "Card of the player: " << this->getCardOfPlayer() << std::endl;
}

void BadDude::set()
{
    Gunslinger::set();
}

main.cpp

#include "bad_dude.h"



void setOfPersonsData(Person * persons[], int howManyPersons);

int main()
{
    std::cout << "Welcome! In this app you can make some data about famous Persons(Gunslinger/PokerPlayers/BadDudes)." << std::endl;
    std::cout << "Write how many workers data you want to have: ";
    int temp;
    while(!(std::cin >> temp))
    {
        std::cin.clear();
        std::cin.ignore();
        std::cout << "Try again: ";
    }
    Person * personData[temp];
    setOfPersonsData(personData, temp);
    for(int i = 0; i < temp; i++)
    {
        std::cout << "Data of " << i+1 << " person." << std::endl;
        personData[i]->show();
        delete personData[i];
    }
    return 0;
}

void setOfPersonsData(Person * persons[], int howManyPersons)
{
    for(int i = 0; i < howManyPersons; i++)
    {
        char chooseOfPerson = 'N';
        do
        {
            std::cout << "Choose "B for BadDude, "G for Gunslinger and P for PokerPlayer: " << std::endl;
            (std::cin >> chooseOfPerson).ignore();
        }
        while (chooseOfPerson != 'B' && chooseOfPerson != 'G' && chooseOfPerson != 'P');
        std::cout << "Write data of " << i+1 << " person." << std::endl;
        if(chooseOfPerson == 'B')
            persons[i] = new BadDude;
        else if(chooseOfPerson == 'G')
            persons[i] = new Gunslinger;
        else
            persons[i] = new PokerPlayer;
        persons[i]->set();
        std::cout << std::endl;
    }
}

When I try to compile this code I get this errors:

main.cpp:42: undefined reference to `BadDude::BadDude(int, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::
__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
main.cpp:44: undefined
 reference to `Gunslinger::Gunslinger(int, double, std::__cxx11::basic_string<char
, std::char_traits<char>, std::allocator<char> 
>, std::__cxx11::basic_string<char, std::char_traits<char
>, std::allocator<char> >)'
main.cpp:46: undefined reference to 
PokerPlayer::PokerPlayer(std::__cxx11::basic_string<char, std::
char_traits<char>, std::allocator<char> >, std::__cxx11:
:basic_string<char, std::char_traits<char>, std::allocator<char> >)'

Why I’m getting this errors? In each class I defined default constructors (with usage of default arguments). Can someone tell me what I did wrong? Thank in advance for you all answers. 🙂

Source: Windows Questions C++

LEAVE A COMMENT