Hi,
I have written a program just to get some understanding of how virtual pointers works w.r.t base and derived class when inherited.
below is my program, the question is when derived class overrides the base function , but function is in private scope of derived, how base pointer can access the private derived class member function?
#include <iostream>
usingnamespace std;
class base{
public:
voidvirtual common_fun() {
cout<<"common_fun base "<<endl;
}
};
class derived: public base {
// public:
void common_fun() {
cout<<"common_fun derived "<<endl;
}
void derived_fun() {
cout<<"derived_fun"<<endl;
}
};
int main() {
base *bptr = new base;
bptr->common_fun(); // outputs common_fun base ==> OK
derived *dptr = new derived;
bptr = dptr;
bptr->common_fun(); // outputs common_fun derived( but how ? common_fun is in private scope of derived )
//derived dobj;
//dobj.common_fun(); // error as expected , since private members cannot be accessed by obj directly.
return 0;
}
#include <iostream>
class base{
public:
voidvirtual common_fun() {
std::cout << "common_fun base \n";
}
};
class derived: public base {
// public:
void common_fun() {
std::cout << "common_fun derived \n";
}
};
int main() {
base x;
derived y;
x.common_fun();
// y.common_fun(); // error: 'virtual void derived::common_fun()' is private
// error: within this context
base* ptr = &y;
ptr->common_fun();
}
The main() uses the interface of base: base::common_fun(). For all it knows, common_fun() is accessible. For example, the *ptr does not have "derived_fun()".
What the user does not need to know is that the derived supplies a modified version of common_fun(). The derived IS-A base and base has public and virtual common_fun().
Herb Sutter did recommend:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
class base{
public:
void common_fun() { common_impl(); }
private:
virtualvoid common_impl() {
std::cout << "common_fun base \n";
}
};
class derived: public base {
void common_impl() {
std::cout << "common_fun derived \n";
}
};
In this version it is more explicit that common_fun() is part of interface and the derived classes can replace the private implementation.
but function is in private scope of derived, how base pointer can access the private derived class member function?
The base class does not know anything about the derived class.
When the base class is instantiated/constructed it places all virtual function into a virtual table. The derived class does the same. I.e. it replaces the functions with the same signature of the base class. Scope doesn't apply here.
Okay, please correct me if my understanding is wrong.
All derived member functions which match the prototype of base virtual functions will be overridden no matter what their scope is (private/public/protected), if invoked by base pointer which has the address of derived object.
#include <iostream>
class Base
{
public:
void hidden_function()
{
std::cout << "Base class hidden function" << std::endl;
}
virtualvoid overridden_function()
{
std::cout << "Base class overridden function" << std::endl;
}
};
class Derived : public Base
{
public:
void hidden_function()
{
std::cout << "Derived class hidden function" << std::endl;
}
void overridden_function()
{
std::cout << "Derived class overridden function" << std::endl;
}
};
int main()
{
Base b;
Derived d;
// As expected
std::cout << "Normal behavior" << std::endl;
b.hidden_function();
b.overridden_function();
d.hidden_function();
d.overridden_function();
// Base class pointer to derived object
Base* b_ptr = &d;
std::cout << "\nBase* pointing to Derived object" << std::endl;
// hidden_function is not virtual, so a Base* only understands
// Base::hidden_function. Call the Base:: version.
b_ptr->hidden_function();
// overridden_function is virtual, so Base* looks up the latest
// local definition of overridden_function in the v-table and
// calls it. Thus Derived::overridden_function is called.
b_ptr->overridden_function();
// Bonus material.
// Using an object of the Derived class, specifically call the
// Base:: implementations of the functions.
std::cout << "\nBONUS! Base:: behavior on Derived object" << std::endl;
d.Base::hidden_function();
d.Base::overridden_function();
return 0;
}
> All derived member functions which match the prototype of base virtual
> functions will be overridden no matter what their scope is
> (private/public/protected), if invoked by base pointer which has the address
> of derived object.
dunno, perhaps it's implementation defined or plain old undefined behaviour
make it simple, don't try to shoot your foot.
also, I think that you're violating liskov there (Preconditions cannot be strengthened in a subtype.)
All derived member functions which match the prototype of base virtual functions will be overridden no matter what their scope is (private/public/protected), if invoked by base pointer which has the address of derived object.
The base class functions will be overriden. The derived functions will override the base class functions.
Scope does not affect the virtual table. When you are trying to access a function no matter if it is virtual or not the scope will have an effect.
In a further derived class you can change the scope again. The virtual function will be overriden even if it was previously private. So again: Scope does not affect the 'virtuality' of functions.
[EDIT]
Actually 'scope' is the wrong term here. See:
when derived class overrides the base function , but function is in private scope of derived, how base pointer can access the private derived class member function?
IMHO
as long as it's virtual it will be able to access directly (override suffix in derived to make sure it virtual)