I have a class A and a class B that inherits from A. A has a foo method which I would like to override in B.
class A {
public:
void foo();
...
}
class B: public A {
public:
void foo();
...
}
The solution to this would of course be to define A::foo() as a virtual method, by declaring it as virtual void foo();. But the problem is that I can't do that, since the A class is defined in a third-party library so I would rather not change its code.
After some searching, I found the override keyword (so that the declaration for B::foo would be void foo() override;), but that didn't help me since that's not what override is for, override can apparently only be used on virtual methods to be sure that the method is really overriding another method and that the programmer didn't make a mistake, and it generates an error if the method isn't virtual.
My question is how can I achieve the same effect as making A::foo virtual without changing any of the code for A, but only the code for B?
A bit late. But you can use std::variant and delegate methods to the two classes A and B according to the concrete type.
If your compiler is not that up to date, use a tagged union instead.
Related
override keyword allows to make sure that the function will get overridden.
I am looking for the reverse functionality. So that - when I write a new function - I want to mark it with something to make sure it will not get accidentally overwritten.
(Also, I do not want to make it static, since it looks like to belong to an object rather than class)
I want to mark it with something to make sure it will not get accidentally overwritten.
You can use the final specifier. Example from cppreference:
struct Base
{
virtual void foo();
};
struct A : Base
{
void foo() final; // A::foo is overridden and it is the final override
void bar() final; // Error: non-virtual function cannot be overridden or be final
};
If you don't want a virtual function to be overridden in the derived class, you can use final:
Specifies that a virtual function cannot be overridden in a derived class or that a class cannot be inherited from.
e.g.
struct Base
{
virtual void foo() final; // foo cannot be overridden in the derived class
};
struct Derived : Base
{
void foo(); // Error: foo cannot be overridden as it's final in Base
};
final is the keyword you are looking for.
Remark: Be aware that override does not "make sure that the function will get overriden" as you put it. override in your derived class does make sure that you actually override a method of a base class, and not just introduce a new method that is similar to a virtual method of the base class.
To make sure that a method is overriden it would have to be pure virtual in your base class.
Also, static works exactly the other way round: static methods belong to the class, non-static methods need an object to be called.
even i think that question is stupid. but i've a little experience.
i have a base class that has such method:
class A{ virtual void func(int)=0 };
and inherited class
class B :public A
{
//how should i write?
//a
virtual void func() { implementation...}
//b
void func() {implementation }
//my target is to redefine a function of ansestor
//i worry that variant b can cover ansestor function and i will not redefine it
//but what if i don't want that the function that was virtual in ansestor, will be virtual in subclass?
i'm confused
}
i don't know that to do. if i don't need this virtual function complete
You ask, "what if i don't want that the function that was virtual in ansestor, will be virtual in subclass?"
Sorry, but every function that is declared virtual in a base class, is also virtual in all derived classes.
It actually doesn't matter whether you use the virtual keyword in the derived-class declaration. Options a and b are identical -- in both cases B::func is virtual.
I suggest your write two small programs, one for each implementation to determine which suits your needs.
In C++ the function signature consists of the function name and function arguments. In a class you cannot have two functions with same signature. So your second (non-virtual) function declaration will generate compiler errors.
In short:
virtual void func() { //implementation}
and
void func() { //implementation }
have the same signature and cannot be declared in the same class.
Virtual means that reimplementation is possible in inherited class(es). Virtual function will allways be virtual no matter the depth of inheritance.
In C++, when a method is declared, I've noticed that sometime the method may have an assignement appended to it.
Could anyone tell me what this is?
For example:
virtual void MyMethod () = 0;
What doe the '= 0' mean. :)
Thanks everyone !!!
It means it's a pure virtual function, i.e. no actual definition of it is available in this class and it must be overridden in a subclass. It's not actually an assignment as such, zero is the only value you can "assign".
And this is C++ syntax; in C# the same would be accomplished with the abstract keyword.
In C++ this means that the method is a pure virtual method.
This means that an instance of this particular class-type cannot be instantiated. You can only create instances of classes derived from this, which override all pure virtual methods in the base class.
A base class with pure virtual methods defines an interface that derived classes have to implement, and is not meant to be used on its own.
Contrary to what calmh claims, as far as I know pure virtual functions can be implemented and they can be called explicitly.
#include <cstdio>
class A
{
public:
virtual void foo() const = 0; //pure virtual
};
void A::foo() const { puts("A::foo"); }
class B: public A
{
public:
virtual void foo() const { puts("B::foo"); }
};
int main()
{
//A a; //this would be an error - main point of having pure virtual functions
B b;
b.foo();
b.A::foo();
}
Usually one wouldn't do this, though, except perhaps if the virtual destructor is pure in a base class (in this case it has to be defined).
In C#, that is a syntax error.
If you meant C++, see calmh's answer.
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
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.