1

booking.h

#ifndef _BOOKING_H_
#define _BOOKING_H_

#include <string>

class Event {
  private:
   std::string event_option;
  public:
   Event(std::string event_option);
   virtual ~Event();
   void list_specific_event_details();
   virtual void list_details();
};

class Films : public Event {
 private:
  std::string movie_option;
 public:
  Films(std::string movie_option);
  void list_details();
};

class Live_Music : public Event {
 private:
  std::string live_music_option;
 public:
  Live_Music(std::string live_music_option);
  void list_details();
};

class Standup_Comedy : public Event {
 private:
  std::string comedy_option;
 public:
  Standup_Comedy(std::string comedy_option);
  void list_details();
};
#endif

booking.cpp

#include "booking.h"
#include <string>
Event::Event(std::string event_option)
{
  this->event_option = event_option;

}

Event::~Event()
{
}


void Event::list_specific_event_details()
{
  return list_details();
}


Films::Films(std::string movie_option) : Event("Films")
{
  this->movie_option = movie_option;

}

void Films::list_details()
{
    //some code ...

    return;

}

Live_Music::Live_Music(std::string live_music_option) : Event("Live_Music")
{
  this->live_music_option = live_music_option;

}

void Live_Music::list_details()
{

    //some code...

  return;

}

Standup_Comedy::Standup_Comedy(std::string comedy_option) : Event("Standup_Comedy")
{
  this->comedy_option = comedy_option;

}

void Standup_Comedy::list_details()
{
    //some code...
  return;

}

main.cpp

#include "booking.h"
#include <iostream>
#include <vector>
#include <string>

int main()
{
  std::vector <Event *> choice;
  choice.push_back(new Films("f"));
  choice.push_back(new Live_Music("l"));
  choice.push_back(new Standup_Comedy("s"));

  for(unsigned i = 0; i < choice.size(); i++)
    {
      choice[i] -> list_specific_event_details();
    }


  for (Event * e: choice) delete e;
  choice.clear();

}

I have written the above block of codes and got an error when I tried to compile it.

The error is as follows:

usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccuWXzBM.o:booking.cpp:(.rdata$_ZTV5Event[_ZTV5Event]+0x20): undefined reference to `Event::list_details()'
collect2: error: ld returned 1 exit status

Why am I getting this error, and how can I solve it?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
MDB
  • 51
  • 5
  • 3
    The given dup is wrong! Here we are talking about an Interface definition and not about undefined refs... A bit fast to press the button... – Klaus Dec 30 '21 at 13:52
  • 2
    Where is `Event::list_details()` in your code? – Eljay Dec 30 '21 at 13:55
  • 2
    @Eljay: Not needed... the missing part is `=0;` – Klaus Dec 30 '21 at 14:03
  • 2
    @Klaus • Maybe. Not sure if Event is intended to be an abstract base class, or just the common base class which itself could be instantiated (it's not instantiated in the code provided, of course, hence the ambiguity). – Eljay Dec 30 '21 at 14:38
  • 1
    @Eljay: But we can take an assumption: The code did not need an instance of `Event` and everything derives from `Event` and all classes are implementing the missing function, it is more or less evident what es meant. Isn't it :-) – Klaus Dec 30 '21 at 14:50
  • 1
    Another interesting aspect to the code, the `list_specific_event_details` non-virtual member function delegate calls the `list_details` virtual member function. That's *almost* the [non-virtual interface](https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface) idiom. Just need to make `list_details` virtual member function private. – Eljay Dec 30 '21 at 14:53
  • 1
    This doesn’t address the question, but names that begin with an underscore followed by a capital letter (`_BOOKING_H_`) and names that contain two consecutive underscores are reserved for use by the implementation. Don’t use them in your code. – Pete Becker Dec 30 '21 at 17:16
  • As an aside, since C++ 11 you can add the `override` keyword after the declaration of the virtual function in the derived class. This (a) makes it clear what the derived class is doing, and (b) will generate a compiler error if the signature does not match that of the base class function. Eg if your base class function was `const` but you neglected to add this in the derived class, this would prevent the wrong function being called. https://en.cppreference.com/w/cpp/language/override – DS_London Dec 31 '21 at 09:54
  • And another aside, prefer std::unique_ptr to using raw pointers. – DS_London Dec 31 '21 at 09:58

1 Answers1

1

You have not defined your method Event::list_details(). If you only want to declare the function but do not want to implement it, that is what is called an Interface, you can make it a pure virtual method with:

class Event
{
...
    virtual void list_details() = 0;
...
};
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Klaus
  • 24,205
  • 7
  • 58
  • 113