This question already has answers here:
Is there a way to prevent a method from being overridden in subclasses?
(14 answers)
Closed 7 years ago.
How can I enforce that a base class method is not being overridden by a derived class?
If you are able to use the final specifier from C++11 you can prevent derived classes from override that method. (Microsoft compilers appear to support the similar sealed with similar semantics.)
Here's an example:
#include <iostream>
struct base {
// To derived class' developers: Thou shalt not override this method
virtual void work() final {
pre_work();
do_work();
post_work();
}
virtual void pre_work() {};
virtual void do_work() = 0;
virtual void post_work() {};
};
struct derived : public base {
// this should trigger an error:
void work() {
std::cout << "doing derived work\n";
}
void do_work() {
std::cout << "doing something really very important\n";
}
};
int main() {
derived d;
d.work();
base& b = d;
b.work();
}
Here's what I get when I try to compile it:
$ g++ test.cc -std=c++11
test.cc:17:14: error: virtual function ‘virtual void derived::work()’
test.cc:5:22: error: overriding final function ‘virtual void base::work()’
If you make the method non-virtual, derived classes cannot override the method. However, in C++03 a class cannot override a method from a base class, and also prevent further derived classes from overriding the same method. Once the method is virtual, it stays virtual.
Don't make it virtual.
This won't prevent deriving from your class and hiding the function (by providing another member function with the same name). However, if your class is not meant to be derived anyway (no virtual destructor, no virtual member functions), that shouldn't be an issue.
well if you want to keep it public, dont declare it virtual.
EDIT: Srikanth commented wondering about overriding a private member function in a derived class.
class A
{
public:
virtual ~A(){};
void test()
{
foo();
};
private:
virtual void foo()
{
std::cout << "A";
};
};
class B : public A
{
public:
virtual void foo()
{
std::cout << "B";
};
};
void test()
{
B b;
A& a = b;
a.test(); // this calls the derived B::foo()
return 0;
}`
well as far as i know you can't do that on c++, you can try to declare it as private. . find more info on this link http://en.allexperts.com/q/C-1040/prevent-overriding-functions-derived.htm
Short answer: there is no need for that. Long answer you can do some twists, but is it worth it?
Related
Consider:
#include <iostream>
class Base
{
public:
virtual void foo() { std::cout << "Base::foo()\n"; };
};
class Derived : public Base
{
public:
void foo() override
{
std::cout << "Derived::foo()\n";
Base::foo();
}
};
int main()
{
Derived obj;
obj.foo();
return 0;
}
This is my code. Why can I call Base::foo() in the Derived class if I already redefined it in Derived class. Why doesn't the compiler delete Base::foo in class Derived after redefine?
"why compiler doesn't delete Base::foo in class Derived after redefine"
Because that isn't what virtual and override do. When you provide an override to a base class function, you do not replace it. You are defining a new version for that function. The base class's implementation continues to exist and to be accessible.
Consider the following code. Someone can still use a Base object, and the behaviour should not be changed because Derived exists. The output for base_obj.foo() should continue to be "Base::foo()" regardless of the existance of Derived. :
#include <iostream>
class Base
{
public:
virtual void foo() { std::cout << "Base::foo()\n"; }
};
class Derived : public Base
{
public:
void foo() override { std::cout << "Derived::foo()\n"; }
};
int main()
{
Derived obj;
obj.foo();
Base base_obj;
base_obj.foo();
return 0;
}
Also consider that multiple classes can derive from Base. I could add a class MyClass : public Base with its own version of foo(), and it should not interfere with how Base or Derived objects behave.
If overriding a member function would cause the base member function to be entirely replaced or removed, it becomes nearly impossible to reason about code without reading carefully every class that derives from it. And unless your IDE provides tools for that, it implies reading all of the code base. It would make it C++ code that uses polymorphism extremely difficult to understand.
The following code is based on the example on page 298 of C++ Templates: the Complete Guide. I removed the parts not relevant to my question.
class Virtual {
public:
virtual void foo() {
}
};
class Base : private Virtual {
public:
void foo() {
std::cout << "Base::foo()" << '\n';
}
};
class Derived : public Base {
public:
void foo() {
std::cout << "Derived::foo()" << '\n';
}
};
int main()
{
Base *p = new Derived;
p->foo(); // calls Derived::foo()
}
I do not understand how the call p->foo() ends up calling Derived::foo. More concretely, the static type of p is Base*. Base::foo is non-virtual. Now, Base privately inherits from 'Virtual', which has its own foo and it looks as if Base::foo somehow gets the virtual specifier from Virtual::foo. What is actually going on here?
The virtualness of foo is inherited from the base class Virtual.
In fact, writing virtual in Derived::foo will be superfluous and many developers will omit it. You cannot undo virtualness once you've marked that function as virtual in a base class.
You can force a call of Base::foo by writing p->Base::foo(); but that's an ugly contrivance.
So heres my code:
#include <iostream>
class cBase
{
public:
void vf(int)
{
std::cout << "cBase\n";
}
};
class cDerived : public cBase
{
public:
void vf(int)
{
std::cout << "cDerived\n";
}
};
int main()
{
cBase b;
cDerived d;
b.vf(0);
d.vf(0);
}
This example hides the function vf() of the base class and calls the vf() function of the derived class. Heres another piece of code:
#include <iostream>
class cBase
{
public:
virtual void vf(int)
{
std::cout << "cBase\n";
}
};
class cDerived : public cBase
{
public:
void vf(int)
{
std::cout << "cDerived\n";
}
};
int main()
{
cBase b;
cDerived d;
b.vf(0);
d.vf(0);
}
Now, the vf() function of the derived class overrides the vf() function of the vase class.
So my question is: what is the point of virtual functions if i can achieve the same result with the default hiding mechanism of c++? Am i missing something here? Thanks in advance!
To make polymorphism work you need to work on pointers or references. When you use dot operator on object that is neither pointer or reference then virtual table is not used to call proper virtual function.
To see how it works, create derived object dynamically, assign it to base class pointer and call your function on it. This will call implementation from your derived class.
virtual functions give run time polymorphism. Your objects will not exhibit run time polymorphism which is when the same code using the same compile-time types can exhibit different behaviour based on the run time types of the objects in question. E.g:
void f(CBase& x) {
x.vf(0);
}
Without vf being virtual in CBase, the CBase::vf will be called even if the run time type of x is CDerived.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calling virtual functions inside constructors
main.cpp
#include <iostream>
class BaseClass {
public:
BaseClass() {
init();
}
virtual ~BaseClass() {
deinit();
}
virtual void init() {
std::cout << "BaseClass::init()\n";
}
virtual void deinit() {
std::cout << "BaseClass::deinit()\n";
}
};
class SubClass : public BaseClass {
public:
virtual void init() {
std::cout << "SubClass::init()\n";
}
virtual void deinit() {
std::cout << "SubClass::deinit()\n";
}
};
int main() {
SubClass* cls = new SubClass;
delete cls;
return 0;
}
Why is init() and deinit() not properly overriden and the BaseClasses' methods are called instead of the SubClasses ones? What are the requirements to make it work?
BaseClass::init()
BaseClass::deinit()
Because you are calling a virtual method inside a constructor. While constructing Base class the derived one (SubClass) isn't still constructed, so actually it doesn't still exist.
It's generally a good practice to avoid calling virtual methods inside constructors.
They are overridden just fine.
But you've invoked them from the base constructor, and when the base constructor is executing, the derived part of the object does not yet exist.
So this is a largely a safety feature, and it's mandated by the C++ standard.
Sample code
#include <iostream>
using namespace std;
class Base
{
public:
virtual void Func()
{
cout << "\nIn base func";
}
};
class Derived : public Base
{
public:
void Func()
{
cout << "\nIn derived";
}
};
class Derived2 : public Derived
{
public:
void Func()
{
cout << "\nIn derived2";
}
};
int main()
{
Base* lnewbase = new Derived2();
lnewbase->Func();
return 0;
}
As an example, in the above code, I do not want Func() of Derived to be inherited (seal in C#) which is why there is no virtual keyword although I am aware that it does not change anything in this case. Is there any way to disallow that function to be inherited while making sure it remains a public method?
No; C++ has no equivalent to C#'s sealed modifier.
There is nothing you can do.
Once you make a function in a base class virtual, there's nothing that can be done to get rid of that aspect of it. I can only think of a few things to almost get around it:
Don't make it virtual;
Make a new, public, non-virtual function in Derived that does what you need.
However, in either case, Derived2 will still be able to make its own version of Func(), which will give you the same problem.