class Base
{
public:
Base()
{
cout<<"base class"<<endl;
fun();
}
virtual void fun(){cout<<"fun of base"<<endl;}
};
class Derive:public Base
{
public:
Derive()
{
cout<<"derive class"<<endl;
fun();
}
void fun(){ cout<<"fun of derive"<<endl;}
};
void main()
{
Derive d;
}
The output is:
base class
fun of base
derive class
fun of derive
Why the second line is not fun of derive?
When you call fun() in the base class constructor, the derived class has not yet been constructed (in C++, classes a constructed parent first) so the system doesn't have an instance of Derived yet and consequently no entry in the virtual function table for Derived::fun().
This is the reason why calls to virtual functions in constructors are generally frowned upon unless you specifically want to call the implementation of the virtual function that's either part of the object currently being instantiated or part of one of its ancestors.
Because you wrote it like that... Your call to the derived class constructor does:
- Base Class Constructor call
|
Call to **fun of Base Class**
- Derived Class Constructor call
|
Call to **fun of the Derived Class**
More details here
Related
I want to call a base class method that, if it's overridden, call the overridden method, otherwise, call base class method.
The idea would be:
I have a base class virtual method that, if some runtime condition is met, then I instantiate a derived class method which completly replaces base class method. Now every time the base class method gets called, the derived method gets called instead.
I think this can be done modifying the virtual method table of the base class and replacing the method address in that table to the "overridden" new function's address.
I don't know if this is possible to archive using only inheritance. If not, which would be the best approach to do this?
Thanks.
What you describe is how non-pure virtual functions work.
I wanto to call the method from base class instance.
Example:
struct Base {
virtual void foo() { std::cout << "base"; };
};
struct Overrides : Base {
void foo() override { std::cout << "overridden"; };
};
int main() {
if (runtime_condition) {
Overrides o;
Base& b = o;
b.foo(); // calls overridden
} else {
Base b;
b.foo(); // calls base
}
};
My code-
class base{
private:
virtual void print(){
cout<<" from base"<<endl;
}
friend void show(base &obj);
};
class drived1 : public base{
private:
void print(){
cout<<" from drived1"<<endl;
}
};
class drived2 : public base{
private:
void print(){
cout<<" from drived2"<<endl;
}
};
void show(base &obj){
obj.print();
}
int main() {
base b;
drived1 d1;
drived2 d2;
show(b);
show(d1);
show(d2);
}
Output:
from base
from drived1 // print function form derived class is called, though it is private.
from drived2 // print function form derived class is called, though it is private.
show(base &obj) is a friend function of base class, but how it is calling the private method from derived class?
This is how C++ works. Access specifiers (public, private, and protected) depend on the static type of your variable, not the dynamic type. In your example, when
void show(base &obj){
obj.print();
}
is compiled, the compiler does not know that the function will be invoked with a drived1 argument. It knows that obj is of type base&, so it only checks whether it can invoke base::print() - which it can because it is a friend of base.
It is calling the private method from derived class because the derived class is being implicitly converted to base class when you call the function.
So, you have an object of type drived1.
Then you pass it to the function show(base&).
The object is being upcasted to base.
Then, in the function show(base&) you use the virtual function print().
The function called is the drived1::print() member function thanks to the way C++ polymorphic behavior works. (A class is called polymorphic if it contains virtual functions).
This function is called and you get output from drived1.
Is there any point to making virtual member functions, overridden from a base class private, if those are public in the base class?
struct base {
virtual void a();
};
struct derived : base {
// ...
private:
void a() override;
};
If you are forced to do a 2-phase construction on the implementation class (i.e. have an init() method as well as or instead of a constructor that has to be called (I know, but there are reasons), then this stops you calling any /other/ methods directly on the instance pointer before you pass it back as an interface pointer. Go the extra mile, make the inheritance private, and have your one public init function return the interface pointer!
Another reason is you just don't /need/ to write public: in a final implementation class declaration, so then by default everything is private. But why you would do that and use struct instead of class I don't know. Perhaps this was converted from class at some point due to a style war?
Looking at your design, I see one cannot call derived::a directly, but only through a base interface.
Is there any point? Consider that, once we have a derived instance, we can always up-cast to its base, so given
derived d;
while d.a() wouldn't compile, we can always do
base & b = d;
b.a(); //which actually calls derived::a
In other words: derived::a is not that private, after all, and I would discourage this design, which can be confusing to the user.
Things change if the members private in derived are private in base, as well: this time it is clear that they just cannot be called directly, outside base or derived.
Let's say we have a couple of functions, and want them to be called conditionally, according to a value passed as an argument to a third one:
struct base
{
void dosomething(bool x)
{
if(x)
{
do_this();
}
else
{
do_that();
}
}
private:
virtual void do_this(){}
virtual void do_that(){}
};
Thus a derived class could be like:
struct derived : base
{
private:
void do_this() override { }
void do_that() override { }
};
and no other class can call them, unless it extended base itself:
derived d;
d.dosomething(true); //will call do_this() in derived
d.dosomething(false); //will call do_that() in derived
d.do_that() //won't compile
Yes, if you inherit the base class as private. Otherwise, it is more of a weird explicit-like restriction - user has to has to make an explicit conversion to use the function - it is generally ill advised as few will be able to comprehend the author's intention.
If you want to restrict some functions from base class, make a private/protected inheritance and via using keyword declare which base-methods you want to be protected/public in the derived class.
The same reasoning as for non-virtual methods applies: If only the class itself is supposed to call it make it private.
Consider the template method pattern:
struct base {
void foo() { a() ; b(); }
virtual void a() = 0;
virtual void b() = 0;
};
struct derived : base {
private:
void a() override {}
void b() override {}
};
int main()
{
derived().foo();
}
Perhaps a and b should have been protected, but anyhow the derived can change accesibility and it requires some documentation so that derived knows how it is supposed to implement a and b.
class Base {
public:
virtual void f();
void f(int);
virtual ~Base();
};
class Derived : public Base {
public:
void f();
};
int main()
{
Derived *ptr = new Derived;
ptr->f(1);
delete ptr;
return 0;
}
ptr->f(1); is showing the following error: "too many arguments in function call".
Why is this isn't possible? isn't derived inherited all the functions form base and is free to use any of them?
I could call it explicitly and it would work but why isn't this allowed?
What you are seeing is called hiding.
When you override the function void f() in the Derived class, you hide all other variants of the f function in the Base class.
You can solve this with the using keyword:
class Derived : public Base {
public:
using Base::f; // Pull all `f` symbols from the base class into the scope of this class
void f() override; // Override the non-argument version
};
As mentioned by #Some Programming Dude : it is because of Hiding.
To understand hiding in relatively simpler language
Inheritance is meant to bring Baseclass variables / functions in Derived class.
But, on 1 condition : "If its not already available in Derived Class"
Since f() is already available in Derived, it doesn't make sense to look at Base class from compiler perspective.
That's the precise reason why you need to scope clarify while calling this function
void main()
{
Derived *ptr = new Derived;
ptr->Base::f(1);
delete ptr;
}
Suppose for time being that Derived do have the access to the function void Base::f(int);. Then it will be a case of function overloading. But, this is invalid case of function overloading since one function f(int);is in Base and other function f(); is in Derived. Function Overloading happens inside a single class. Function Overriding happens across classes. The example you posted is a case of Name Hiding in Inheritance
"Derived *ptr" This definition will only allow "ptr" to access all the member functions which are defined via Derived class or its child class. But, it will not allow u to access the member functions which are coming in Derived class because of inheritance.
If u want to access base class version of function "f" then use "Base *ptr" and it will choose the correct version of function automatically as shown :)
class Base {
public:
virtual void f()
{
cout<<"Here 2"<<endl;
}
void f(int x)
{
cout<<"Here 1"<<endl;
}
virtual ~Base() {}
};
class Derived : public Base {
public:
void f()
{
cout<<"Here 3"<<endl;
}
virtual ~Derived() {}
};
int main()
{
Base *ptr = new Derived;
ptr->f(1);
delete ptr;
return 0;
}
output is
Here 1
I want to call a overridden method from a base class method called by the derived class:
class Base {
Base();
virtual void function override() {}
void basefunction() {
override();
}
class Derived : public Base {
Derived() {
basefunction();
}
virtual void function override() {
cout << "derived" << endl;
}
}
main() {
Base* d = new Derived();
}
The constructor of Derived call the basefunction, which should call the overridden function "override()"from the derived class.
But it doesn't. It calls Base::override(). I understand why this function is called, but how can I implement my issue, that the basefunction calls the override function from the derived class?
If the override function is defined as pure virtual the declaration in the main function is not allowed.
Is it possible to show us the code you are using? The one you give has to be completed in order to be compilable.
When completed in the obvious way, I get the result I expect: display of "derived".
There is something related which could be the problem you see, or it could be unrelated. During the execution of the constructor and the destructor, the dynamic type is the same as the type of the constructor/destructor. So if you have the call to basefunction in Base() instead of in Derived(), indeed it is Base::override which is called and not Derived::override. During the execution of Base::Base(), Derived's members have not been constructed yet and it would be dangerous to call a member which could access them.