C++ virtual functions implementation outside the class
Asked Answered
C

4

11

I am new to C++. While trying sample polymorphism code, I found that base class virtual function definition in derived class is possible only when defined within the derived class or outside with declaration in derived class.

Following code gives error:

class B
{
public:
    virtual void f();
};

void B::f() {
    std::cout<<"B::f";
}

class D : public B
{
public:
    void f2() {int b;}
};

// error: no "void D::f()" member function declared in class "D"
void D::f() {
    std::cout<<"D::F";
}

It works if I declare f() inside D. I was wondering why do I need to explicitly declare the function again when it is already declared in Base class. The compiler can get the signature from Base class right?

Thanks in advance..

Cyn answered 21/12, 2010 at 11:25 Comment(8)
you have made f() into a virtual function in the base class, thus it is abstract and need to be implemented in your D class as well. You can read more about virtual function here parashift.com/c++-faq-lite/virtual-functions.html#faq-20.1Montgolfier
@Montgolfier no, it's not true, if it was abstract =0 would follow the method declaration.Nobile
@starcorn: "thus" is the wrong word. a virtual function may or may not be pure. also, "abstract" describes the class, not the virtual function. and B does not declare a pure virtual function.Plenteous
@starcorn: I guess B::f() is not abstract as its definition for B exists. Does it need to be defined inline in B to ensure its concreteness?Cyn
"I was wondering why do I need to explicitly declare the function again". These are the rules of the game c++.Sigh
@to all, yes i understand it now. Didn't drink my coffee today...Montgolfier
Of course B should have a virtual (or protected) destructor.Everglades
B::f() and D::f() are different functions so it makes sense you have to declare both in the header. If B::f() were pure virtual too and D::f() did not exist then D would also be abstract and creating an instance would cause a compiler error. That could not be enforced if the file might be overridden somewhere in a compilation unit. (No, a link error would not really work).Everglades
B
9

You can't add members to a class outside of the class definition. If you want D to have an override for B::f then you have to declare it inside the class definition. Those are the rules.

Declaring a member in a base class doesn't automatically give derived classes an identical member. Inheriting from the base gives the derived class all the members of the base class so you can choose whether to override, hide or add to the base classes members but you have to indicate a choice to override in the class definition by declaring the overriding function.

Betterment answered 21/12, 2010 at 11:34 Comment(2)
Further, even if you don't explicitly override f() in class D, B::f() is accessible (i.e., can be called in D) without any problem. It's only when you want to override, you have to redefine in D as well.Extrinsic
Thanks all. I guess its just the way the language and compiler is designed. I was just thinking logically that if compiler can get the signature from base class, why can't it automatically assume this is overridden implementation due to same signature.Cyn
E
3

Even though D derives from B and therefore you can call f() on an instance of D, it does not mean you do not need to put the declaration into the header.

Any function you implement must be explicitly declared in the header.

You do not need, however, to put its implementation in there. Just

class D : public B
{
public:
   /*virtual*/ void f();
};

and you can optionally choose whether to include the word "virtual" here

Everglades answered 21/12, 2010 at 11:35 Comment(0)
N
1

In C++, your class definition tells the compiler which functions the class implements. So if you want to write a function "D::f()", you must have f() in the class definition for D.

The fact that function "B::f()" has been defined in the base class is irrelevant. Each class definition must explicitly declare the functions that it implements.

Naumann answered 21/12, 2010 at 11:47 Comment(0)
A
1

Change code for class D as below and try :

class D : public B
{
public:
    void f() override;
};

// error: no "void D::f()" member function declared in class "D"
void D::f() {
    std::cout << "D::F";
}
Amish answered 26/2, 2019 at 18:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.