Izzo
Izzo

Reputation: 4928

Why must I re-declare a virtual function from an inherited class?

I'm working on a simple C++ program and am having a difficult time understanding a compiler error I was getting. The issue was caused by me attempting to create a derived class from a base class. I've posted my code below with the same structure but have changed the names.

BaseClass.h

#ifndef BASECLASS_H
#define BASECLASS_H

class BaseClass {

    public:
        BaseClass(void);

        virtual int method1(void) = 0;
        virtual int method2(void) = 0;
        virtual float method3(void) = 0;

};

#endif // BASECLASS_H

DerivedClass.h

#ifndef DERIVEDCLASS_H
#define DERIVEDCLASS_H

#include "DerivedClass.h"

class DerivedClass: public BaseClass
{

    public:
        DerivedClass(void);     
};

#endif // DERIVEDCLASS_H

DerivedClass.cpp

#include "DerivedClass.h"

DerivedClass::DerivedClass(void)
{
}

int DerivedClass::method1(void)
{
  // TODO
} 

int DerivedClass::method2(void)
{
  // TODO
}

float DerivedClass::method3(void) 
{
  // TODO
}

When attempting to compile this, I get the following error for all the virtual methods:

no 'int DerivedClass::methodX()' member function declared in class 'DerivedClass'

As soon as I declare these methods in the 'DerivedClass.h', the errors go away since the compiler is now aware of the methods.

However, I'm confused. Why was it necessary to re-declare the pure virtual functions in DerivedClass.h? When I #include DerivedClass.h, that will automatically include BaseClass.h, thus I assume my DerivedClass.cpp should be fully aware of the methods. Am I doing something incorrect?

Upvotes: 12

Views: 9835

Answers (4)

Raindrop7
Raindrop7

Reputation: 3911

you should override all the base class pure virtual functions to be able to instantiate derived class.

  • you cannot define a base class member function from derived class.

in your example you are trying to define method1 and method2 and method3 which are not members of DerivedClass!! you have to declare them yourself in your derived class. compiler doesn't do it for you.

so your Derivedclass.h will look like:

#ifndef DERIVEDCLASS_H
#define DERIVEDCLASS_H

#include "BaseClass.h"

class DerivedClass: public BaseClass
{

    public:
        DerivedClass(void); 

        virtual int method1(void); // not pure function
        virtual int method2(void);
        virtual float method3(void);
};

#endif // DERIVEDCLASS_H

Upvotes: 0

Sam Varshavchik
Sam Varshavchik

Reputation: 118292

A very non-intuitive reason why overridden virtual methods must be derived in the base class stems from the fact that C++ allows different parts of the class to be placed into different files, into different translation units.

With some other languages (I'm looking in Java's direction), a single class must be placed in a single file. This is not true with C++. It is perfectly legal for a class to have some of its methods declared in one translation unit, and other methods declared in another translation unit, which could be in a file in some different directory altogether.

Each such file gets compiled separately and individually. When compiling one translation, the C++ compiler has no knowledge of any other translation unit, any other file, that might contain other pieces of the same class.

Now let's say that you are allowed to omit an overriden virtual method from the class declaration. This creates an immediate problem: when compiling the class's constructor, it is necessary for the compiler to know whether the class overrides any virtual methods from any of the superclasses, in order to correctly assemble the virtual table dispatch for the class being constructed. Without an explicit declaration, the compiler has no way of knowing whether or not some other translation unit might define an overridden virtual method.

And that's why overridden virtual methods must be explicitly included in the class's declaration. In conclusion: because C++ formally specifies phase 9, the linkage phase, with the actual compilation carried on in earlier phases, overridden methods must be explicitly declared.

Upvotes: 0

anatolyg
anatolyg

Reputation: 28241

When you declare a method in a derived class, you say to the compiler:

I want to override this method in this class

So if you don't declare a method in the derived class, you say:

I don't want to override this method; derived class's implementation is the same as the one in the base class

In your case, the base class declares them as pure virtual, so in this case it can be paraphrased:

I don't want to implement this method in this class

If you try to define a method but not declare it, you contradict yourself. The compiler detects that (to protect you from your own negligence).

Upvotes: 7

krzaq
krzaq

Reputation: 16421

It doesn't work this way. You need to declare the methods you're going to define, whether they're overriding a virtual method or not.

This isn't just an unreasonable requirement of the language. Without this you would be unable to define partially virtual class, i.e., you could have BaseSubtype that has common implementation of method1() but requires classes derived from it to implement method2() and method3()

Upvotes: 11

Related Questions