Can I call a derived class through a base class function pointer, as shown in the example below?
I understand that my example works, but is it guaranteed to always do so (Assuming the object actually implements the function!), or is this just an idiosyncrasy of the compiler I'm using?
By this logic can't one simply derive all their classes from "CBase" (which in this case is empty so I guess no overhead) and ignore the type in the function pointer?
#include <iostream>
struct CBase
{
};
struct CDerived : CBase
{
void MyFunction()
{
std::cout << "Called OK" << std::endl;
}
};
typedef void (CBase::*FunctionPointer)();
int main()
{
CDerived* base = new CDerived();
FunctionPointer pointer = static_cast<FunctionPointer>(&CDerived::MyFunction);
(base->*pointer)();
delete base;
}
Example usage scenario: A derived class that takes one or more pointers to "callbacks" in the base class. Can the callback type just be defined using the derived class and thus forgo the need for a template?
When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function.
Is it possible that a base class pointer pointing to a Derived class object in C++? Yes, it is possible. Next, we have called functions fun1, fun2, and fun3 with the help of pointer p.
The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class. However, inheritance is transitive.
In C++, a derived class object can be assigned to a base class object, but the other way is not possible.
A pointer to derived class is a pointer of base class pointing to derived class, but it will hold its aspect. This pointer of base class will be able to temper functions and variables of its own class and can still point to derived class object. Writing code in comment?
A derived class is a class which takes some properties from its base class. It is true that a pointer of one class can point to other class, but classes must be a base and derived class, then it is possible. To access the variable of the base class, base class pointer will be used.
It is true that a pointer of one class can point to other class, but classes must be a base and derived class, then it is possible. To access the variable of the base class, base class pointer will be used.
However, since Derived has a Base part, a more interesting question is whether C++ will let us set a Base pointer or reference to a Derived object. It turns out, we can! #include <iostream> int main() { Derived derived { 5 }; // These are both legal!
Yes, it's guaranteed to work. From [expr.static.cast]:
A prvalue of type “pointer to member of
D
of type cv1T
” can be converted to a prvalue of type “pointer to member ofB
of type cv2T
”, whereB
is a base class (Clause 10) ofD
, if cv2 is the same cv-qualification as, or greater cv-qualification than, cv1.70 If no valid standard conversion from “pointer to member of B of type T” to “pointer to member of D of type T” exists (4.11), the program is ill-formed. The null member pointer value (4.11) is converted to the null member pointer value of the destination type. If classB
contains the original member, or is a base or derived class of the class containing the original member, the resulting pointer to member points to the original member.
In this case, we're converting a pointer to member of CDerived
of type void()
to a poitner to member of CBase
ov type void()
. CBase
is a base of the class containing the original member, so the resulting pointer points to the original member.
From [expr.mptr.oper]:
Abbreviating pm-expression.*cast-expression as
E1.*E2
,E1
is called the object expression. If the dynamic type ofE1
does not contain the member to whichE2
refers, the behavior is undefined.
In this case, pointer
pointers to the original member. base
has that member. So this is fine.
Note that in your example, base
is actually a CDerived*
. It would be just as valid to write:
CDerived d;
CBase* b = &d;
(b->*pointer)(); // ok - the dynamic type of b contains the member to which pointer refers
You can use this method but casting pointers is not a good practice at all. Method you are using has nothing common with polymorphism. A better way to implement this is using a virtual
function and a pure
function.
Your base class must have a pure function (pure functions also virtual) and your derived class must implement this function. So you will be able to call this function with base pointer and implementation of your derived class will be called.
#include "stdafx.h"
#include <iostream>
struct CBase
{
virtual void MyFunction() =0; // this is a `pure` function. Pure means it's a virtual and may not have implementation. If a class has at least one pure function it means this class is an abstract class
virtual ~CBase()=default; // gotta be or we will have a memory leak during `delete`..
};
struct CDerived : CBase
{
virtual void MyFunction() override
{
std::cout << "Called OK" << std::endl;
}
};
//typedef void (CBase::*FunctionPointer)();
int main()
{
CBase* base = new CDerived();
base->MyFunction();
delete base;
system("pause");
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With