Should a virtual function essentially have a definition?
Asked Answered
I

5

9

Is it essential to have a definition for a virtual function?

Consider this sample program below:

#include <iostream>

using namespace std;

class base
{
   public:
      void virtual virtualfunc();
};

class derived : public base
{
   public:
   void virtualfunc()
   {
      cout << "vf in derived class\n";
   }
};

int main()
{
   derived d;
   return 0;
}

This gives the link-error:

In function base::base():: undefined reference to vtable for base

I do not have the definition for the virtual function in base class. Why is this error occurring even though I have not explicitly invoked the virtual function?

The interesting thing which I find is that if I do not instantiate an object of class derived, the link error is no longer there. Why is this? What has instantiation got to do with the above link error?

Insecurity answered 27/12, 2011 at 7:25 Comment(1)
Re your edit: if you don't instantiate a derived or a base, why would the linker have to do anything with any method from those two classes? If the classes aren't referenced, the linker has no reason to even try to look them up in the object files. (Unless you're building a library.)Underwrite
L
12

The ISO C++ Standard specifies that all virtual methods of a class that are not pure-virtual must be defined.

Reference:

C++03 Standard: 10.3 Virtual functions [class.virtual]

A virtual function declared in a class shall be defined, or declared pure (10.4) in that class, or both; but no diagnostic is required (3.2).

So either you should make the function pure virtual or provide a definition for it.

If you are using gcc, You might get some weird errors if you fail to follow this standard specification. The gcc faq doccuments it as well:

The ISO C++ Standard specifies that all virtual methods of a class that are not pure-virtual must be defined, but does not require any diagnostic for violations of this rule [class.virtual]/8. Based on this assumption, GCC will only emit the implicitly defined constructors, the assignment operator, the destructor and the virtual table of a class in the translation unit that defines its first such non-inline method.

Therefore, if you fail to define this particular method, the linker may complain about the lack of definitions for apparently unrelated symbols. Unfortunately, in order to improve this error message, it might be necessary to change the linker, and this can't always be done.

The solution is to ensure that all virtual methods that are not pure are defined. Note that a destructor must be defined even if it is declared pure-virtual [class.dtor]/7.

Li answered 27/12, 2011 at 7:41 Comment(0)
P
8

You need to provide an implementation of a virtual function ( with its default behaviour ) unless you define the function to be "pure virtual".

So your example could be:

class base
{
   public:
      void virtual virtualfunc() {} //intentionally do nothing;
};

or

class base
{
   public:
      void virtual virtualfunc()=0; //pure virtual;
};
Precocity answered 27/12, 2011 at 7:30 Comment(0)
U
3

You either need to provide a definition, or mark it as abstract/pure-vitual.

void virtual virtualfunc() = 0;
Underwrite answered 27/12, 2011 at 7:29 Comment(1)
Concise and pretty much says it all.Literator
S
1

In response to the error about the vtable: the virtual command in this case tells c++ to produce a virtual table of the methods in the base class. In this way when you use polymorphism, C++ is able to replace the base class virtual methods with the methods from the derived class with the same name during run time. This error is telling the user that this replacement is not possible. To fix this error, you will either need to implement the method or set it as pure virtual by adding "=0" at the end of the definition.

In response to the edits: The reason you are not getting an error when you instantiate the object as a base class is because the base class does not need to access the virtual table. On the other hand if you actually try to use this method, you should get an error since no implementation exists. In other words even though you can instantiate an object of the base class its not a complete class.

Sexed answered 29/4, 2013 at 17:52 Comment(1)
This is the deeply reason!!Yea
B
0

Yes you would need a body, but perhaps what you are referring to is called a pure virtual functions, which would not need a definition in the base class.

The syntax to define those is as follows:

void virtual virtualfunc() = 0;
Bugger answered 27/12, 2011 at 7:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.