I saw code in a derived class recently in which the programmer put virtual in front of the functions overridden. Is this common? I thought it was very odd and it kind of caught me off guard.
Edit: I'm not asking what virtual does, I'm asking why someone would put virtual in a derived class that is already overriding virtual functions in its base class.
EX:
class B {
public:
virtual void foo();
....
};
class D : public B {
public:
virtual void foo(); // could have just put void foo();
...
};
virtual is needed for overrideable functions at the highest (least derived) level. It is optional, but harmless at lower (more derived) levels. It's good for self-documenting the code.
These answers (and this practice) are outdated. As of C++11, you should use the override keyword to explicitly specify that a virtual function overrides another virtual function. Your compiler will throw an error if you try to override something that isn't a virtual function in the base class!
It is very common. Many style guides recommend it, e.g. Google.
The purpose is to enhance readability of the code.
I don't see anything odd in it. In many cases (if not most of the time) programmers create the declaration of the overriding function in the derived class by copy-pasting it from the base class. There's no point in spending the additional effort to manually remove the redundant virtual specifier. Moreover, the explicit virtual makes it easier to see which functions are virtual.
Another way to enhance readability is to use something like this:
class B {
public:
virtual void foo();
....
};
class D : public B {
public:
/*override*/ void foo();
...
};
I'll assume that you know the purpose of the virtual keyword but wondering why it suddenly appears in a subtype. If I am mistaken, my answer probably won't make much sense but any C++ reference will do.
It is perfectly legal to put virtual in a derived class. As a result, if you have a reference or pointer to that class or any of its subclasses, invocations of this function would be bound dynamically based on the runtime type.
While legal, however, it is not considered good design to have a nonvirtual method in the base class and virtual in an overridden version.
One reason is that you could have an instance of the derived class, and then one pointer to base and one pointer to the derived, and have both pointers aiming at this instance. Invoking the same function on each pointer would then have a different result, since invoking on the pointer declared with the base class would target the definition in the base class.
This will help if future derivations also. If someone wants to derive class D and have virtual functions, then its easy to understand
Related
With the struct definition given below...
struct A {
virtual void hello() = 0;
};
Approach #1:
struct B : public A {
virtual void hello() { ... }
};
Approach #2:
struct B : public A {
void hello() { ... }
};
Is there any difference between these two ways to override the hello function?
They are exactly the same. There is no difference between them other than that the first approach requires more typing and is potentially clearer.
The 'virtualness' of a function is propagated implicitly, however at least one compiler I use will generate a warning if the virtual keyword is not used explicitly, so you may want to use it if only to keep the compiler quiet.
From a purely stylistic point-of-view, including the virtual keyword clearly 'advertises' the fact to the user that the function is virtual. This will be important to anyone further sub-classing B without having to check A's definition. For deep class hierarchies, this becomes especially important.
The virtual keyword is not necessary in the derived class. Here's the supporting documentation, from the C++ Draft Standard (N3337) (emphasis mine):
10.3 Virtual functions
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, 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.
No, the virtual keyword on derived classes' virtual function overrides is not required. But it is worth mentioning a related pitfall: a failure to override a virtual function.
The failure to override occurs if you intend to override a virtual function in a derived class, but make an error in the signature so that it declares a new and different virtual function. This function may be an overload of the base class function, or it might differ in name. Whether or not you use the virtual keyword in the derived class function declaration, the compiler would not be able to tell that you intended to override a function from a base class.
This pitfall is, however, thankfully addressed by the C++11 explicit override language feature, which allows the source code to clearly specify that a member function is intended to override a base class function:
struct Base {
virtual void some_func(float);
};
struct Derived : Base {
virtual void some_func(int) override; // ill-formed - doesn't override a base class method
};
The compiler will issue a compile-time error and the programming error will be immediately obvious (perhaps the function in Derived should have taken a float as the argument).
Refer to WP:C++11.
Adding the "virtual" keyword is good practice as it improves readability , but it is not necessary. Functions declared virtual in the base class, and having the same signature in the derived classes are considered "virtual" by default.
There is no difference for the compiler, when you write the virtual in the derived class or omit it.
But you need to look at the base class to get this information. Therfore I would recommend to add the virtual keyword also in the derived class, if you want to show to the human that this function is virtual.
The virtual keyword should be added to functions of a base class to make them overridable. In your example, struct A is the base class. virtual means nothing for using those functions in a derived class. However, it you want your derived class to also be a base class itself, and you want that function to be overridable, then you would have to put the virtual there.
struct B : public A {
virtual void hello() { ... }
};
struct C : public B {
void hello() { ... }
};
Here C inherits from B, so B is not the base class (it is also a derived class), and C is the derived class.
The inheritance diagram looks like this:
A
^
|
B
^
|
C
So you should put the virtual in front of functions inside of potential base classes which may have children. virtual allows your children to override your functions. There is nothing wrong with putting the virtual in front of functions inside of the derived classes, but it is not required. It is recommended though, because if someone would want to inherit from your derived class, they would not be pleased that the method overriding doesn't work as expected.
So put virtual in front of functions in all classes involved in inheritance, unless you know for sure that the class will not have any children who would need to override the functions of the base class. It is good practice.
There's a considerable difference when you have templates and start taking base class(es) as template parameter(s):
struct None {};
template<typename... Interfaces>
struct B : public Interfaces
{
void hello() { ... }
};
struct A {
virtual void hello() = 0;
};
template<typename... Interfaces>
void t_hello(const B<Interfaces...>& b) // different code generated for each set of interfaces (a vtable-based clever compiler might reduce this to 2); both t_hello and b.hello() might be inlined properly
{
b.hello(); // indirect, non-virtual call
}
void hello(const A& a)
{
a.hello(); // Indirect virtual call, inlining is impossible in general
}
int main()
{
B<None> b; // Ok, no vtable generated, empty base class optimization works, sizeof(b) == 1 usually
B<None>* pb = &b;
B<None>& rb = b;
b.hello(); // direct call
pb->hello(); // pb-relative non-virtual call (1 redirection)
rb->hello(); // non-virtual call (1 redirection unless optimized out)
t_hello(b); // works as expected, one redirection
// hello(b); // compile-time error
B<A> ba; // Ok, vtable generated, sizeof(b) >= sizeof(void*)
B<None>* pba = &ba;
B<None>& rba = ba;
ba.hello(); // still can be a direct call, exact type of ba is deducible
pba->hello(); // pba-relative virtual call (usually 3 redirections)
rba->hello(); // rba-relative virtual call (usually 3 redirections unless optimized out to 2)
//t_hello(b); // compile-time error (unless you add support for const A& in t_hello as well)
hello(ba);
}
The fun part of it is that you can now define interface and non-interface functions later to defining classes. That is useful for interworking interfaces between libraries (don't rely on this as a standard design process of a single library). It costs you nothing to allow this for all of your classes - you might even typedef B to something if you'd like.
Note that, if you do this, you might want to declare copy / move constructors as templates, too: allowing to construct from different interfaces allows you to 'cast' between different B<> types.
It's questionable whether you should add support for const A& in t_hello(). The usual reason for this rewrite is to move away from inheritance-based specialization to template-based one, mostly for performance reasons. If you continue to support the old interface, you can hardly detect (or deter from) old usage.
I will certainly include the Virtual keyword for the child class, because
i. Readability.
ii. This child class my be derived further down, you don't want the constructor of the further derived class to call this virtual function.
Say I have an abstract class
class NecessaryDanger
{
public:
virtual void doSomethingDangerous() =0;
}
and a class that is derived from this class:
class DoesOtherStuff : public NecessaryDanger
{
//stuff
void otherMethod();
void doSomethingDangerous();
}
is there a way I can only allow access of doSomethingDangerous() like
DoesOtherStuff d;
d = DoesOtherStuff();
d.otherMethod(); //OK
d.doSomethingDangerous(); //error
NecessaryDanger* n = &d;
n->doSomethingDangerous(); //OK
I am not very good at C++ yet, so the code above may not be quite right, but you maybe get the idea. I have a set of classes that need to have the ability to do "something dangerous" (in their own special way) that could cause problems if more than one object of these classes does this dangerous thing. I would like to have a manager class that has a NecessaryDanger pointer to only one object. If the method doSomethingDangerous could only be called by a NecessaryDanger object, then it would be more difficult for an accidental call to doSomethingDangerous to happen and cause me headaches down the road.
Thanks in advance for the help. Sorry in advance if this is a dumb question!
Sure. Just make it private in the derived class and public in the base.
Of course, if NecessaryDanger is a public base, then anyone can cast and call. You might want to make it a private base and use friend.
class DoesOtherStuff : private NecessaryDanger
{
//stuff
void otherMethod();
private:
void doSomethingDangerous();
friend class DangerManager;
}
Remove the virtual classifier in the superclass so that the compiler does compile-time binding based on the variable type instead of run-time binding based on the object type.
Building on Potatswatter's response :)
Here is Herb's advice: (especially 1 and 2) applicable in this context.
Guideline #1: Prefer to make
interfaces nonvirtual, using Template
Method.
Guideline #2: Prefer to make
virtual functions private.
Guideline #3: Only if derived classes need to invoke the base implementation of a
virtual function, make the virtual
function protected.
For the special case of the destructor
only:
Guideline #4: A base class destructor
should be either public and virtual,
or protected and nonvirtual.
I have an abstract class with a couple pure virtual functions, and one of the classes I derive from it does not use one of the pure virtual functions:
class derivative: public base
{
public:
int somevariable;
void somefunction();
};
anyways, when I try to compile it, I get an error (apparently, a class is still considered abstract if derive from an abstract class and don't override all pure virtual functions). Anyways, it seems pointless to define a function
int purevirtfunc(){return 0;}
just because it needs to be defined through a technicality. Is there anyway to derive a class from an abstract class and not use one of the abstract class's pure virtual functions?
If your derived class doesn't "use" the base class pure virtual function, then either the derived class should not be derived from the base, or the PVF should not be there. In either case, your design is at fault and needs to be re-thought.
And no, there is no way of deleting a PVF.
A pure virtual class is an interface, one which your code will expect to be fulfilled. What would happen if you implemented that interface and didn't implement one of the methods? How would the code calling your interface know that you didn't implement the method?
Your options are:
Implement the method as you describe (making it private would indicate that it shouldn't be used).
Change your class hierarchy to take into consideration the design change.
The purpose of deriving from abstract classes is that external code can use the abstract class and expect that all functions have been implemented properly. Being able to unimplement a method would defeat this purpose, making the code uncompilable. You're free to throw an exception, if you so choose, however.
It's not a technicality at all. If your derived class does not exhibit all of the behavior of the parent, it should not be derived from the parent. This is a major design smell, and you probably need some design refactoring.
When you inherit from a class that has pure virtual functions, you MUST implement those functions. If you don't, then your derived class is also abstract, and you can't create an object of the derived class.
No. Either provide a default implementation in the base class or a simple implementation in the derived class, as you suggested.
There were already good answers, but if you want more info from the theoretical OO design side, check out the Liskov substitution principle.
Allowing this wouldn't make any sense. What would happen if you called the function without an implementation? A runtime error (that would be silly)? You could argue that it could a compile time error in some cases, but this is not possible if the exact type is not known (e.i. you pass a pointer to an instance of the derived class to a function).
As many people have already stated, it sounds like either the base method shouldn't be pure virtual or you should rethink whether your derived class really ISA base.
However, it is possible to provide an implementation for the pure virtual method in the base class. This can act like a default implementation for derived classes, but you still require the derived class to choose the base class's implementation explicity.
I don't know if that will help you with your problem or not.
No, there isn't. The convention in late bound languages when this situation occurs (as it legitimately might, but consider your design to see whether this method can be moved elsewhere, perhaps to its abstract class), is to raise an exception, and make sure that users of that method know that some implementations may raise that exception.
Seems i faced with the same problem, when trying to hide method getVertex() in derived class.
Maybe it's help.
class Body2D
{
public:
virtual ~Body2D() = default;
virtual double getCenter() const = 0;
virtual double getVertex() const = 0;
};
class Ellipse : public Body2D
{
public:
Ellipse(){};
double getCenter() const override{};
private:
double getVertex() const override{};
};
Couldn't you just do
class Foo {
public:
virtual void foo() = 0;
};
class Bar {
public:
virtual void foo() = delete;
};
Whilst trawling through some old code I came across something similar to the following:
class Base
{
public:
virtual int Func();
...
};
class Derived : public Base
{
public:
int Func(); // Missing 'virtual' qualifier
...
};
The code compiles fine (MS VS2008) with no warnings (level 4) and it works as expected - Func is virtual even though the virtual qualifier is missing in the derived class. Now, other than causing some confusion, are there any dangers with this code or should I change it all, adding the virtual qualifier?
The virtual will be carried down to all overriding functions in derived classes. The only real benefit to adding the keyword is to signify your intent a casual observer of the Derived class definition will immediately know that Func is virtual.
Even classes that extend Derived will have virtual Func methods.
Reference: Virtual Functions on MSDN. Scroll down the page to see
The virtual keyword can be used when
declaring overriding functions in a
derived class, but it is unnecessary;
overrides of virtual functions are
always virtual.
Here's an interesting consequence of not needing to declare overriding functions virtual:
template <typename Base>
struct Derived : Base
{
void f();
};
Whether Derived's f will be virtual depends on whether Derived is instantiated with a Base with a virtual function f of the right signature.
Someone told me once that very old C++ compilers, not conforming to the spec, require virtual to be set for all subclasses. That's not an issue anymore.
One danger of following this practice is that people may not realise they need the virtual keyword on functions which are intended to be virtual. This is most likely to be people coming from languages where there is no concept of non-virtual functions (eg: Java, REALbasic). As a corollary, you can't tell when virtual has been deliberately omitted because a function is supposed to be non-virtual.
I suspect some code analysis tools may also not be smart enough to pick up the inherited virtuality.
Let's say we have
class A {
public:
virtual int foo() { cout << "foo!"; }
}
class B : public A {
public:
virtual int foo() =0;
}
class C : public B {
public:
virtual int foo() { cout << "moo!"; }
}
Is this really overriding? I think this is actually overloading.
What is the meaning of making something like this, design-wise?
We got a base class A. Then we got an abstract derived class B which is derived from the concrete class A, and then a realization of B via C.
What are we doing here and does it make any sense?
Overloading would mean that you had two functions of the same name but with different parameters. That's not the case here.
Example:
int functionA() { /*...*/ };
int functionA(int someParameter) { /*...*/ };
Overriding means rewriting a function with the same parameters in a subclass. That is what you presented as an example.
That's the definition part. Now on to the design:
When you have a pure virtual function, concrete subclasses have to override it. So by adding a pure virtual function, you ensure that all subclasses provide the same set of functions (=interface). This seems to be the case in the sample code.
But it is not a very good example, as the concrete superclass already implements a default functionality for foo(). When there is an abstract subclass that redefines it to be purely virtual, it is a sign for me that the class hierarchy is flawed because a subclass (and the callers of foo()) usually should be able to fall back to the default implementation. It's a bit hard to explain with such an abstract example, but a hierarchy like this is a bit suspicious to my eye.
It seems to me that the only effect of the pure virtual method here is to make B an abstract class.
It's still overriding, because when you have a pointer p of type A* to instance of class C, p->foo() still calls C::foo()
Probably, the designer wanted to insert an abstract class in the hierarchy deriving from some concrete class, and force overriding of the method in subclasses. I don't think it's terribly wise.
You're saying that classes deriving from B must implement int foo();. You might want to do something like this to force other programmers to think about how they want foo() to behave, but I think it's a bad idea - in reality they're likely to implement by calling A::foo().
If you just want to make B abstract, give it a pure virtual destructor - you'll also need to provide an implementation of the destructor to avoid link error though.