I looked over the internet for an answer to my questions but couldn't find any, so here I am.
Is it correct to specify override to my function that derived from a pure virtual:
class baseClass
{
public:
virtual void myFunction() = 0;
}
class derivedClass : public baseClass
{
public:
virtual void myFunction() override;
}
Is this correct?
And my second question is:
Do I have to specify virtual in the derivedClass for my function even though no class will inherite from my derived class (it will be final)?
Thank you a lot for your answers!
Is this correct?
Yes. Override ensures that the function is virtual and overriding a virtual function from the base class. The program is ill-formed (a compile-time error is generated) if this is not true.
Do I have to specify virtual in the derivedClass for my function even though no class will inherite from my derived class (it will be final)?
No you don't. But even if you leave away the virtual specifier it remains virtual. Because it has been declared virtual in your BaseClass.
If some member function vf is declared as virtual in a class Base, and
some class Derived, which is derived, directly or indirectly, from
Base, has a declaration for member function with the same
name
parameter type list (but not the return type)
cv-qualifiers
ref-qualifiers
Then this function in the class Derived is also virtual (whether or
not the keyword virtual is used in its declaration) and overrides
Base::vf (whether or not the word override is used in its
declaration). Base::vf does not need to be visible (can be declared
private, or inherited using private inheritance) to be overridden.
cppreference.com
Also, please remember that you should define a virtual destructor (can be empty one) in baseClass, in order to guarantee a proper resource deallocation in the derived classes.
Related
Note: I am not asking why a parent class need to have virtual method.
I remember something coding guideline like that(I don't remember well and just try to express as my own word,hope I have correct wording): if the parent class have virtual method,the derived class should also at least have one virtual method, even the derived class would not have derived class from itself, if the derived class really no need to have any virtual method, set destructor as virtual. The reason behind it is something like "prevent duplicate virtual table", what is it talking about?
And I also remember a related example like that:
class A{
virtual f();
};
class B : public A{
};
B as no derived class, if B has no virtual method, the consequence is something like "any place that include B will have a duplicate virtual table generated by compiler" (also is just expressed from my impression), what is the meaning of that (if it is true)?
Note the following:
If the base class has a virtual member function other than a destructor, the derived class inherits that function.
If the base class declares a member function as virtual, and the derived class declares a member function of the same name with the same argument types, then the derived class function is automatically virtual, and overrides the base class's function.
If the base class has a virtual destructor, the derived class's destructor is automatically virtual, whether user-declared or not, and overrides the base class's destructor.
The example you gave is not in any way problematic. I would advise you to forget everything you think you remember about this coding standard.
Here is a very basic example:
class Base {
public:
virtual void sayHi() const {}
virtual void sayHello() {}
virtual ~Base(){}
};
class Derived : public Base {
public:
virtual void sayHi() {}
virtual void sayHello() const {}
};
int main()
{
Base *b = new Base();
Base *d = new Derived();
return 0;
}
The Base's vptr, in 'b' has virtual functions of Base class. The derived class object 'd' however, on inspection, list virtual functions of only base.
The question here is not, why are the functions not being overridden so the use of override keyword isn't required here. The question is, why doesn't a particular class's VTable contain its own virtual functions? In this case why vtable of 'd' doesnt contain D::sayHi and D::sayHello?
I am open to downvotes, but be brave to mention and tell the reason.
edit:
I know that the CONSTness might look wrong here, but the question is not about overriding.
This is specifically tried out in VS2012 Update4
Here you have different function overloads that do not override the defined virtual functions:
virtual void sayHi() const {}
virtual void sayHello() {}
void sayHi() {} // non virtual function with a different signature (no const)
void sayHello() const {} // non virtual function with a different signatuere (const)
If you want to avoid such subtle errors, use the keyword override : if the function that you think overrides a virtual function of the base class has a different signature or doesn't even exist (e.g.typo...) the compiler will generate an error.
Edit following your edit:
I see that you've updated the code to make the overloaded non overriding functions virtual as well.
Now the vtable of the derived function contains four distinct functions. However, through the base pointer you can only access the virtual functions defined in the base. This is why the MSVC debugger shows you only 2:
By the way, the debugger seems to always show the vtable as a member of the Base. But if you look at the assembler generated, you'll see the mangled names of all the virtual functions of the derived class in its vtable:
Your Hi function does not override the base class Hi function as their const specifiers are wrong.
The same is true for your Hello functions, albeit the other way round.
If you use C++11 or later you can use the override keyword to make sure this doesn't happen.
It was already mentioned that you are not overriding the functions as you are changing the functions signature by adding a const.
Concerning your actual questions:
It will use the vtable-pointer from the base class to point to its own vtable that has different entries. Thats just how it works. It "looks" like the base class but behaves "different". Thats polymorphic behaviour in C++.
If each deriving class would add its own vtable, a lot of things would be broken in C++. Multiple vtable pointers will only be part of an instance of a class, which derives from multiple classes containing virtual functions or when using virtual inheritance.
Consider the following classes in C++11:
class Base
{
public:
virtual void foo() = 0;
}
class Sub1 : public Base
{
public:
virtual void foo() override {};
}
class Sub2 : public Base
{
public:
void foo() override {};
}
What are the consequences of making the overridden function non-virtual as in Sub2?
An override of a virtual function is always virtual regardless of whether it's declared as such. Thus, having or not having the virtual keyword in the declaration of Sub2::foo() has no effect whatsoever as far as the language is concerned, since the override keyword means that the function must override a member function of a base class. From ยง10.3 [class.virtual]/p2 of the standard, emphasis added:
If a virtual member function vf is declared in a class Base and in
a class Derived, derived directly or indirectly from Base, a
member function vf with the same name, parameter-type-list (8.3.5),
cv-qualification, and ref-qualifier (or absence of same) as Base::vf
is declared, then Derived::vf is also virtual (whether or not it
is so declared) and it overrides Base::vf. For convenience we say
that any virtual function overrides itself.
Omitting the word virtual does not make the function non-virtual. It does reduce the verbosity, the amount of visual noise, or in short, the way that the source code text can make an impression of just being too long-winded without any specific part of it introducing anything really new that can capture the reader's attention so that it all appears more or less like a gray mass of text, which of course can lead to some important details being overlooked, which is to say, inadvertently ignored. The override keyword is preferable.
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
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.
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.
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.
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.
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.
I am modifying code that the grand-parent class is a pure virtual which include a pure virtual version of function XYZ ; the then parent class declares XYS as virtual and it has an implementaion for it. Then the child class declares XYZ as a regular function with a different implementation from that of the parent1 9which in itself is confusing to me). When I call the function XYZ from another object, which implementation gets executed? the parent one or the child one? Thanks
When I call the function XYZ from another object, which implementation gets executed? the parent one or the child one?
Let's find out:
struct A {
virtual void f() = 0;
};
struct B : A {
virtual void f() { cout << "B::f\n"; }
};
struct C : B {
virtual void f() { cout << "C::f\n"; }
};
int main() {
C().f();
return 0;
}
Pure virtual functions don't need a definition (as opposed to virtual functions), and they make their class abstract. Abstract classes can't have an object created from, except when they act as base class object.
Your confusion seems to center around the presence or absence of the virtual keyword. If a function is declared virtual in a base class, then a function of a derived class, whether or not you put a virtual keyword, will automatically become virtual if it has the same name, parameter types and constness.
So if you call XYZ on a grandparent* or parent* that actually points to a child object, then the XYZ of the child object will be executed.
A pure virtual function just means that no class with a pure virtual function can be instantiated. Once the parent class overrides it, it just becomes a normal virtual function. Once a function has been declared virtual in a base class, it is always virtual, regardless of whether or not the inheriting class defines it as virtual.
Edit: That means that calling it is just calling a virtual function like any other- that is, the most derived class's implementation will be called.
A pure virtual function usually has no implementation and creates the "abstractness" of the class.
The compiler will not let you create an instance of a class that is abstract. Any class that derives from this class remains abstract unless all the pure virtual functions it inherits have been implemented (and it doesn't add any new ones). Such a class is called concrete.
Note that a pure virtual function may be given an implementation (although it cannot be inlined for syntax reasons). In addition, you can have a pure virtual destructor, and then it must be given an implementation (even if it is an empty one).
You indicate a pure virtual function by adding =0 at the end thus:
virtual void foo(); // not pure
virtual void bar() = 0; // pure virtual
class sample
{
public:
virtual void fun(); //virtual function
virtual void sun()=0; //pure virtual function
};
Pure virtual function is declared by assigning 0, as done above. Providing definition for pure virtual functions is optional, while providing definition for virtual functions is compulsory, otherwise it will not compile. Also, you cannot create instance of a class that defines even a single pure virtual function.
A virtual function is one that can be overridden in a derived class.
A pure virtual function is one that has no implementation at all and therefore MUST be overridden in a derived class.
You cannot create an instance of a class with a pure virtual function, or a class that derives from it unless you override any pure virtual functions with your own implementation.
In the case of a virtual function, if you call xyz on an object of a child class, always the child version of xyz (Child::xyz()) will be executed.
It would not be a case with non-virtual overridden methods. Then if you had a pointer Parent* ptr = &child, ptr>xyz() would actually execute Parent::xyz(). But in your case it is Child::xyz(). That is why you use the virtual keyword.