0

I encountered a problem while I was studying about C++ virtual functions. The code is as follows:

#include <iostream>
#include<string>
using namespace std;
class Event {
public:
    string name;

    virtual string getEvent();
  void setName(string name) {
    this -> name = name;
  }
};
class Sports: public Event {
  public: string getEvent() {
    return name;
  }
};
int main() {
  Sports s;
  Event *ptr;
  ptr = &s;
  s.setName("Chess");
  cout << "Event Name: " << ptr -> getEvent() << endl;
  return 0;
}

And I am getting the following compilation error:

c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\hp\AppData\Local\Temp\cciS3jrR.o:main.cpp:(.text$_ZN5EventC2Ev[__ZN5EventC2Ev]+0xa): undefined reference to `vtable for Event'
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\hp\AppData\Local\Temp\cciS3jrR.o:main.cpp:(.text$_ZN5EventD2Ev[__ZN5EventD2Ev]+0xa): undefined reference to `vtable for Event'
collect2.exe: error: ld returned 1 exit status

After some experiments, I came to know that if I define the virtual function in the base class, the program compiles fine. Can someone please guide me and tell me what I'm missing here? I expected the output to be Event Name: Chess, it would be really helpful if someone could explain to me why won't I get the expected output.

Tanish Sharma
  • 47
  • 1
  • 6
  • You have to define all non-pure virtual functions. The linker could just as easily complained about an undefined reference to `Event::getEvent`. – 1201ProgramAlarm Apr 25 '20 at 03:07
  • @1201ProgramAlarm Thanks for ur quick reply. So, does it mean that I must define the non-pure virtual functions, even if I don't want them to perform a task? How will I do that, for example, in the code that I mentioned? – Tanish Sharma Apr 25 '20 at 03:12
  • The same way you define any member function. In this case you'll need the base class version to return something. (`string Event::getEvent() { return string(); }`) – 1201ProgramAlarm Apr 25 '20 at 03:15
  • @TanishSharma use a pure virtual method when a derived class MUST override it, regardless of any default implementation in the base. If a virtual method is not pure virtual in the base, you MUST provide an implementation for it, even an empty one, eg: `virtual string getEvent() {}` or `virtual string getEvent(); ... string Event::getEvent() {}` – Remy Lebeau Apr 25 '20 at 03:16
  • Thanks to both of You sir. @1201ProgramAlarm Can you please answer one more of my doubts? I have never seen { return string(); }. What kind of return statement is it and what does it mean? What do the parentheses signify here? Thanks again. – Tanish Sharma Apr 25 '20 at 03:28
  • Its returning a default constructed string object. You could also use `return string{};` or `return "";` or `string s; return s;`. – 1201ProgramAlarm Apr 25 '20 at 03:29
  • Oh now I get it, Thanks a lot. – Tanish Sharma Apr 25 '20 at 03:33
  • The problem is that `Event::getEvent` has not been defined, The peculiar wording of the error message is because gcc puts the vtable for a class in the source file where it finds the definition of the class's first non-inline virtual function. Since `Event::getEvent` is not defined inline and there are no other virtual functions it's the first non-inline virtual function. And since it hasn't been defined, the vtable for `Event` also hasn't been defined. Yes, too much mechanism. – Pete Becker Apr 25 '20 at 12:36

0 Answers0