I have a question, here are two classes below:
class Base{
public:
virtual void toString(); // generic implementation
}
class Derive : public Base{
public:
( virtual ) void toString(); // specific implementation
}
The question is:
If I wanna subclass of class Derive perform polymophism using a pointer of type Base, is keyword virtual in the bracket necessary?
If the answer is no, what's the difference between member function toString of class Derive with and without virtual?
C++03 §10.3/2:
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 and
same parameter list as Base::vf is
declared, then Derived::vf is also
virtual (whether or not it is so
declared) and it overrides
Base::vf.
That keyword there is strictly optional and makes no difference at all.
The virtual property is inherited from the base class and is assumed to be present even if you don't type it out.
The compiler already knows from the 'virtual' keyword in the base class that toString is a virtual method. No need to repeat it.
A function once a virtual always a virtual.
So in any event if the virtual keyword is not used in the subsequent classes, it does not prevent the function/method from being 'virtual' i.e. be overridden. So the following guideline might help from a team development point-of-view :-
If the function/method is supposed to
be overridden, always use the
'virtual' keyword. This is especially
true when used in interface / base
classes.
If the derived class is supposed to
be sub-classed further explicity
state the 'virtual' keyword for every
function/method that can be
overridden.
If the function/method in the derived
class is not supposed to be
sub-classed again, then the keyword
'virtual' is to be commented
indicating that the function/method
was overridden but there are no
further classes that override it
again. This ofcourse does not prevent
someone from overriding in the
derived class unless the class
is made final (non-derivable), but it
indicates that the method is not supposed to be
overridden.
Ex: /*virtual*/ void someFunc();
It doesn't matter to the compiler whether or not you supply the virtual keyword on derived versions of the function.
However, it's a good idea to supply it anyway, so that anyone looking at your code will be able to tell it's a virtual function.
It's a matter of good style, and the user-programmer knows what's going on. In C++0x you can use [[override]] to make it more explicit and visible. You can use [[base_check]] to force the usage of [[override]].
If you don't want or can't do that, simply use the virtual keyword.
If you derive without virtual toString, and you cast an instance of Derive back to Base, calling toString() would actually call Base's toString(), since as far as it know's that's an instance of Base.
Related
This question already has answers here:
virtual qualifier in derived class
(4 answers)
Closed 7 years ago.
Quite often I see code (e.g. here) where the override is also declared virtual even if the class is not meant to be subclassed again. E.g.
class A {
virtual void foo();
}
class B : public A {
virtual void foo();
}
// there is no subclass of B (and most likely there will never be one)
In my naive C++ beginners thinking, I find it much clearer and more explicit not to declare B::foo virtual in case it is not meant to be overridden. I.e.
class B : public A {
void foo();
}
Many methods I write are not meant to be overridden. On the other hand I understand virtual as indication that the method was designed to be overridden. I guess it is just a matter of taste, however I am not 100% sure:
Does it make any difference if B::foo() is declared virtual (assuming B will not be used as base class)?
There is no requirement to mark an overriden virtual method virtual in a derived class. The decision whether a method is virtual or not is made in the least derived class.
It is, however, a good idea to mark a virtual method explicitly virtual in a derived class for two reasons:
It serves as documentation for future readers of your code. That could be you, so this should be a strong incentive.
If someone decides to remove the virtual qualifier in the base class, a compiler can catch the bug before the application ships, and issue a warning. There is no requirement for a particular implementation to issue a diagnostic in this case, though.
If your compiler supports C++11, using the override specifier in derived classes is recommended, as it performs additional validation. It is required for an implementation to issue an error, if a base class method is not declared virtual, but the derived class uses an override specifier.
No, it doesn't make any difference. If A::foo is declared as virtual in the base class, B::foo is also virtual: whether you declare it as such or not.
A method doesn't lose is virtual qualifier, so if A::foo() is virtual, B::foo() is also virtual even without repeating the keyword in B::foo() declaration.
Before override, it may be a style to repeat virtual in derived classes to remember that it is a overridden method, now we can use override instead (and compiler check that it is correct whereas it can't do it simply with virtual)
Many methods I write are not meant to be overridden
So you may mark them as final to forbid the method to be overridden (you may also mark the class final if it makes sense).
This question already has answers here:
What's the point of a final virtual function?
(11 answers)
Closed 5 years ago.
In various explanations of C++11's final keyword, I'm seeing examples like this.
class base
{
public:
virtual void f() final;
};
class derived : public base
{
public:
virtual void f(); // Illegal due to base::f() declared final.
};
Is this actually a useful use of final? Why would you declare a virtual function in a base class (implying that it will be usefully overrideable in derived classes) and then immediately mark it as final (negating that implication)? What is the utility of virtual void f() final?
I can see the value of marking derived::f() final rather than base::f(). In this case, base::f() presumably had a good design-based reason for why f() should be virtual, and derived::f() separately has a good design-based reason for why no further-derived class should override its implementation.
If you don't want the function overridden polymorphically, why not just leave off the virtual keyword? Of course, derived classes might still override the function non-polymorphically. Is the purpose of virtual void f() final in the base class therefore to make base::f() firmly non-overrideable in any way—either as a virtual or non-virtual function? If so, then it seems a bit unfortunate that we must add the virtual keyword in this case only to enable use of final. I would think that it should then be legal to mark even non-virtual functions as final.
Why use virtual void f() final for a function originating in a base class when the sense of virtual and the sense of final seem to contradict?
Is there any sense in marking a base class function as both virtual and final?
Yes, at least temporarily.
I found myself in a relatively large and unfamiliar existing C++ source code base. Much of the code was written prior to C++11. I found that I wanted to ensure that all overrides of a virtual function in a base class were marked with override. The hard part is locating all of those overrides.
I marked the virtual function in the base class with final, and the compiler quickly showed me where every single override was declared. It was then very easy to decorate the overrides how I wanted, and remove the final from the virtual in the base class.
You can mark it virtual to indicate that it is 'virtual' in the class you are inheriting from (even though you don't have to do this), and mark it final to indicate that no class deriving from your class may override it further. This may happen when you are implementing an abstract base class, for example. This is C++11, so it's not useful; override is a much better indication, since it is enforced by the compiler.
Another possibility: you want this method not to be overridden, but you want to be able to change that without recompilation. Remember that virtual means it is in the virtual table. even if the compiler will not let you override it.
I think the purpose of the example you have shown is to demonstrate priorities between virtual and final, and nothing more. It is a minimal use of final, not a useful one.
Marking a non-virtual method as final makes no sense, since you cannot override them anyway. If you want the compiler to prevent hiding, that is a completely different issue, that has nothing to do with the method being final. In a sense, non-virtual methods are final already, but hidable.
The alternative is a non-virtual function. But non-virtual function can be hidden by a derived class. So if you want to prevent a function hiding, it can be specified as virtual final one.
I need to understand these statements:
virtual string FOOy() = 0;
virtual string FOOx( bool FOOBAR ) = 0;
I am not sure if the function being virtual has anything to do with it...
Although your testcase is woefully incomplete, from the presence of the keyword virtual it looks like this is inside a class definition.
In such a context, = 0 is not an assignment at all, but a piece of confusing syntax that marks the virtual member function as being "pure". A pure virtual member function may have an implementation (defined elsewhere), but one is optional and the function's very existence prohibits the class from being instantiated.
That is, a class with pure virtual member functions may be called "abstract".
Your peer-reviewed C++ book covers the topic in much greater detail.
It means that the method is pure, or abstract. It means that the method is meant to be declared by extending classes (thanks for clarifying this--see comments below).
The = 0 syntax is how you declare a pure virtual function in C++. A pure virtual has no implementation in the class declaring it -- any subclass must implement the function in order to be instantiable.
http://www2.research.att.com/~bs/glossary.html#Gpure-virtual-function
That makes the function a pure virtual function. This means that the class that declares the function is abstract, and subclasses must provide an implementation for this function.
By adding the = 0 you are declaring the virtual function to be pure virtual function. This means that derived classes must implement the method before they can be instantiated. Normally the base class does not have implementation.
This is also called an abstract function in other languages, such as Java and C#.
It simply means, that the implementor (Original writer) of the class in which FOOx and FOOy intended it to be used as an interfaces to its Derived Classes.
And these being virtual means, it will be possible that the derived class' implementation will be used, using the base class' pointer. So its being usable as an interface becomes possible by declaring them as virtual.
And finally, answering your question. Value-assignment, specifically assigning 0 to a function means, explicitly saying, that function doesn't has any definition. (Though you can specify a definition for it, but it will need to be called explicitly by the derived classes)
I have an existing class that declares a virtual method and defines a default implementation. Now I want to overload that method with a differend parameter and also give a default implementation. Additionaly I want to enforce the constraint, that if the first method got overridden by a subclass then the second (overloaded) virtual method must be overridden too.
Is this even possible inside C++? If so, is it possible at compile time?
Example code:
class ParamA {};
class ParamB {};
class Base
{
public:
virtual void method(ParamA a)
{
// default behavior
}
virtual void method(ParamB b)
{
// default behavior
}
}
class Derived : public Base
{
public:
virutal void method(ParamA)
{
// special behavior
}
}
My goal is to detect classes of type Derived and enforce them to implement their verison of method(ParamB b).
No, you can't specify complex constraints on which sets of member functions must be overridden. The only constraints apply to individual functions; pure virtual (=0) to mandate overriding, and (in C++11) final to prevent overriding.
The best you can do is make both functions pure virtual, forcing the derived class to override both. This at least forces the author of the derived class to think about what needs overriding; it's impossible to override one and forget the other one.
You can still provide a default implementation, so that derived classes that don't want to override either function only need very short overrides that call the default versions.
I think C++ does not provide any means to detect such missing override in a child.
#larsmans: Making both methods pure virtuals leads to missing the default implementation.
#js_: could you elaborate a bit on your actual issue? What you are searching for seems to be conceptually not that clear to me.
How about creating a Parent class from which Base will inherit? These 2 functions will be pure virtual in the Parent class. The derived classes will inherit Parent (and not Base), and will have to implement both functions.
If you all you have to work with is the parent class, then no. It's not possible neither at compile time, nor as a runtime check.
Of course, you could introduce some macros (like say OVERRIDE_METHODS... I'm sure you see what I'm talking about), but nothing can prevent the users from ignoring them and override only one of said methods.
Plus such macros will make the code pretty ugly.
If a function is declared non-virtual in a derived class when the base class function was virutal, why does it invoke a vtable lookup on calling the function on its pointer? The function is clear from the scope.
In C++ if you declare a method virtual in the base class then it's virtual also in derived class, even if the virtual keyword is omitted.
For documentation purposes is however in my opinion nice to repeat it anyway.
You cannot make a function non-virtual, so it will stay virtual and a call to the function is in general also virtual. Of course, there are situations where the compiler will be able to optimize this and do a direct call, but apparantly not in your scenario.
The function is still virtual (assuming it has the same or a covariant signature). Using virtual when overriding is redundant.
Virtual methods created to affect on derived class (When you mark a method as virtual. It will use vtable on derived classes). And the overrided methods will be virtual.
When a class inherits a virtual function, any new, overriding declaration of that function will automatically be made virtual, even if the virtual keyword is not used.