ChatGPT解决这个技术问题 Extra ChatGPT

Do ALL virtual functions need to be implemented in derived classes?

This may seem like a simple question, but I can't find the answer anywhere else.

Suppose I have the following:

class Abstract {
public:
    virtual void foo() = 0;
    virtual void bar();
}

class Derived : Abstract {
public:
    virtual void foo();
}

Is it ok that class Derived does not implement the bar() function? What if not ALL of my derived classes need the bar() function, but some do. Do all of the virtual functions of an abstract base class need to be implemented in the derived classes, or just the ones that are pure virtual? Thanks


C
Community

Derived classes do not have to implement all virtual functions themselves. They only need to implement the pure ones.1 That means the Derived class in the question is correct. It inherits the bar implementation from its ancestor class, Abstract. (This assumes that Abstract::bar is implemented somewhere. The code in the question declares the method, but doesn't define it. You can define it inline as Trenki's answer shows, or you can define it separately.)

1 And even then, only if the derived class is going to be instantiated. If a derived class is not instantiated directly, but only exists as a base class of more derived classes, then it's those classes that are responsible for having all their pure virtual methods implemented. The "middle" class in the hierarchy is allowed to leave some pure virtual methods unimplemented, just like the base class. If the "middle" class does implement a pure virtual method, then its descendants will inherit that implementation, so they don't have to re-implement it themselves.


And even this (implementation of pure virtual functions) only if they are intended to be instanciated (in contrast to being an abstract base class themselves).
That is what I thought. But am doing this in my project, and I am getting a linking error saying that there is an "unresolved external symbol" for Derived::bar(); But I never declared bar within Derived, so why is the linker looking for the function body?
@pixelpusher Of course Derived::bar has a function body, that of Abstract::bar. So it seems the translation unit where that is defined (is it even defined anywhere?) is not linked into the translation unit where it is called.
@Rob: They only need to implement the pure ones. It is misleading. The derived classes don't necessarily need to implement pure virtual functions either.
I appreciate the help but @trenki hit the nail on the head. Though you were also correct Christian Rau, as it was NOT defined.
t
trenki

Only the pure virtual methods have to be implemented in derived classes, but you still need a definition (and not just a declaration) of the other virtual methods. If you don't supply one, the linker might very well complain.

So, just putting {} after your optional virtual method gives you an empty default implementation:

class Abstract {
public:
    virtual void foo() = 0; // pure virtual must be overridden
    virtual void bar() {}   // virtual with empty default implementation
};

class Derived : Abstract {
public:
    virtual void foo();
};

A more involved default implementation would go into a separate source file though.


C
Community

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

Simply put the rule is: If your derived class overiddes the Base class virtual method then it should provide a definition as well, If not then the Base class should provide the definition of that method.

As per the above rule in your code example, virtual void bar(); needs a definition in the Base class.

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.

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.


J
Jason

Yes, that's fine ... you only need to implement any pure virtual functions in order to instantiate a class derived from an abstract base class.


C
CodeCodeCode

Yes, Its correct that a Derived class has to OVERRIDE the function which is Pure Virtual in the Parent Class. Parent class having a Pure Virtual Function is called Abstract Class only because it's Child class must give their own body of the Pure Virtual Function.

For the Normal Virtual Functions:- Its not necessary to override them further, as some child class may have that function, some may not have.

Main purpose of Virtual Function mechanism is Run Time Polymorphism, whether main purpose of Pure Virtual Function(Abstract Class) is to make it mandatory to have the same name Function with own's body.