How much memory would it take to declare a function pointer. How about a function pointer pointing to a member function of a class?
[EDIT:] I guess my question wasn't clear. I am aware a function pointer to a member function takes up more memory space, I am wondering why...
The answer is platform-dependent. You could find the answer for your specific platform by using sizeof.
Size of pointer to member function may not necessarily be the same as that of a regular function pointer, so you should write a test to output them both:
#include <iostream>
using namespace std;
void foo() {}
struct C {
void bar();
};
int main() {
cout << sizeof(&foo) << endl;
cout << sizeof(&C::bar) << endl;
return 0;
}
Demo.
It's up to the implementation, but typically a pointer to a member function takes up the same amount of space a regular pointer takes up, plus the amount of space the offset to the this pointer takes, which is typically the same size as a pointer. So you would expect a pointer to a member function to be twice the size of a regular pointer.
Consider:
#include <iostream>
using namespace std;
class Base
{
public:
int q;
Base() { ; }
void BaseFunc () { cout << this << endl; }
};
class Derived : public Base
{
public:
int r;
Derived() { ; }
virtual void DerivedFunc () { cout << this << endl; }
};
int main ()
{
Derived f;
f.BaseFunc();
f.DerivedFunc();
void (*p1)();
void (Derived::*p2)();
cout << sizeof(p1) << " " << sizeof(p2) << endl;
}
Example output:
0x7fffe4c3e328
0x7fffe4c3e320
8 16
So a pointer to a member function has to store two pieces of information -- which function to call and how to adjust the this pointer to point to the right section of the member data.
And for those who think the adjuster can be computed from the types, try this main:
int main ()
{
Derived f;
void (Derived::*p1)();
p1 = &Derived::BaseFunc;
(f.*p1)();
p1 = &Derived::DerivedFunc;
(f.*p1)();
}
The two invocations of (f.*p1)(); require different adjusters even though the types are the same. And, of course, invoking BaseFunc through a Base::(*)() pointer would require a different adjuster from invoking the same function through a Derived::(*)() pointer.
Related
I would like to perform a down casting at execution time.
For what I read, if I want to do it, I need to compare the typeid of my polymorphic pointer with those of my derived classes, then do the casting in the correct type.
Plus, let's assume that I have a large number of derived classes.
This implies I have to write a long switch or list of if.
I would like to reduce this effort by using a list of classes to check.
This could look like:
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
using namespace std;
class BaseShapes
{
virtual int run() = 0;
};
class ClassRectangle : public BaseShapes
{
int run()
{
std::cout << "I am a Rectangle. " << std::endl;
return 0;
}
float get_length () {return 12.4;};
float get_width() {return 6.2;};
};
class ClassCircle : public BaseShapes
{
int run()
{
std::cout << "I am a Cricle. " << std::endl;
return 0;
}
float get_diameter() {return 5.3;};
};
float function_only_for_Rectangle(ClassRectangle *rectangle)
{
// a function coming from a library that I cannot touch and that requires a derived type.
// But for the example I do something dummy!
return rectangle->get_length()
};
auto downcast_function (auto *p)
{
enum ListOfTypes {
ClassCircle,
ClassRectangle,
// and a lot more differents classes
};
for ( int fooInt = ClassCircle; fooInt < ClassRectangle; fooInt++ )
{
ListOfTypes fooItem = static_cast<ListOfTypes>(fooInt);
if (typeid(p) == typeid(fooItem))
{
auto pCasted =dynamic_cast<fooItem>(p);
return pCasted;
}
}
std::cout<< "downcast_function warning: no typeid is matching !" << std::endl;
return p;
};
int main(void)
{
// Beginning of main.
cout << "(Start)" << endl;
std::unique_ptr<BaseShapes> Shape1(new ClassRectangle());
auto p=Shape1.get();
//function_only_for_Rectangle(p); // not working since p is of type BaseShapes*
auto pbis=downcast_function(p); // should be of type ClassRectangle*
function_only_for_Rectangle(pbis);
// End of the main.
cout << "(End) " << endl;
return 0;
}
// EoF
So how can I write the downcast_function ? Or in other words, how can I iterate over a list of class types in order to make a typeid comparison and a casting ?
More details:
I agree that in this dummy example, I could simply override a function for each derived class and that is a much better way to deal with polymorphism. But I need to downcast, this is a constrain coming from a more complex problem where they are things that I am not allowed to changed. So, the question here is not why downcast but how.
To give a bit more details about my constrains are:
To start from a base pointer.
Get a derived pointer and give it to an external function (here called function_only_for_Rectangle, so I cannot modify this function).
I cannot do a simple and direct dynamic_cast<ClassRectangle>(p) because the type of p (or equivalently Shape1) will change at running time. This means that Shape1 can have "randomly" any derived type from BaseShapes. So I need something "automatic" and this is why I was thinking about iterate over all derived types and downcast according to the typeid match (but I am open to better ideas).
All the classes can modified if needed.
You say "polymorphic" but what you want to do is the opposite of it.
Instead of trying to work against polymorphism you could actually use it. If all subclasses have their own implementation of a virtual function then the caller does not need to care what the actual dynamic type of the object is. That is runtime polymorphism in a nutshell.
I suppose the naming for run is only for the example. Give it a better name, supply a default implementation in the base class, implement specific behavior in ClassRectangle and let the caller call it. No need to cast.
class BaseShapes
{
virtual int do_something_rectangly() { return 0;}
~virtual BaseShapes() = default;
};
class ClassRectangle : public BaseShapes
{
int do_something_rectangly() override
{
std::cout << "I am a Rectangle. " << std::endl;
return 0;
}
};
class ClassCircle : public BaseShapes
{
// does not override do_something_rectangly()
};
int function_for_any_base_shape(BaseShapes& s)
{
return s.do_something_rectangly();
};
int main(void)
{
// Beginning of main.
cout << "(Start)" << endl;
std::unique_ptr<BaseShapes> Rec1(new ClassRectangle());
function_for_any_base_shape(*pbis);
cout << "(End) " << endl;
return 0;
}
Concerning your edit:
I cannot do a simple and direct dynamic_cast(p) because the type of p (or equivalently Shape1) will change at running time. This means that Shape1 can have "randomly" any derived type from BaseShapes. [...]
Either I misunderstand what you wrote completely or you misunderstand how dynamic_cast works. dynamic_cast does already check what the dynamic type of the object is:
BaseShapes* b1 = new ClassCircle;
if(ClassRectangle* d = dynamic_cast<ClassRectangle*>(b1))
{
// cast is sucessfull
function_only_for_Rectangle(d);
} else {
// dynamic type of b1 is not ClassRectangle
}
To call function_only_for_Rectangle you do not need to be able to cast to all subtypes of ClassBase. You only need to dynamic_cast to a pointer to ClassRectangle and check if the cast was sucesfull.
Let me start stating I'm a self-made programming passionate, so forgive the unprofessional language, not speaking English very well I got support from translator. From what I've understood it seems that casting a pointer to an object and one of its functions member cannot be made to a dummy structure. In particular, the call to the member function cannot be made in this way:
#include <iostream>
struct _T{};
class Class1
{
public:
void print()
{ std::cout << "Class1::print ...." << std::endl; }
int sum(int value)
{ return m_dato+value; }
private:
int m_dato { 10 };
};
int main()
{
Class1 item;
void(_T::*func)();
int(_T::*fsum)(int);
Class1* p1=&item;
auto p2=reinterpret_cast<_T*>(p1);
func =reinterpret_cast<void(_T::*)()>(&Class1::print);
(p2->*func)();
fsum =reinterpret_cast<int(_T::*)(int)>(&Class1::sum);
auto dato=(p2->*fsum)(55);
std::cout << "Dato: " << dato << std::endl; // ok 65..
std::cout << "Fine procedura ...." << std::endl;
return 0;
}
Now besides guessing that the pointer to Class1 may not be contained in the _T pointer, I don't understand why this code works without problems on all conditions (in case the class is derived and the function is virtual, in the case of multiple inheritance, in the case that the function is present only in the base class, etc ...). At the end I'm not telling the compiler to call an address of a class (Class1), that the compiler knows well, and that this function is at some offset from the class pointer and that the signature of that function is similar to the one stored later after the cast.
Consider following programme
#include <iostream>
#include <typeinfo>
template <class T>
void Output(const char * Str, T Func)
{
void *Ptr = reinterpret_cast<void *>(Func);
std::ptrdiff_t Num = reinterpret_cast<std::ptrdiff_t>(Ptr);
std::cout << Str << " " << Num << std::endl;
}
class TAnotherBase { long a[10]; };
struct TBase {
typedef void (TBase::*TFunc)();
TFunc Func;
TBase(TFunc F) {
Func = F;
Output("Ctor TBase ", Func);
}
void CallF() {
std::cout << "This in TBase: " << typeid(this).name() << " " << this << std::endl;
(this->*Func)();
}
};
struct TDerived: public TAnotherBase, public TBase {
TDerived(): TBase(static_cast<TBase::TFunc>(&TDerived::F)) {
Output("Ctor TDerived ", &TDerived::F);
CallF();
}
void F() {
std::cout << "This in TDerived::F: " <<typeid(this).name() << " " << this << std::endl;
}
};
int main(int argc, char **argv) {
TDerived Derived;
return 0;
}
It generates this output:
Ctor TBase 4197502 (1)
Ctor TDerived 4197502 (2)
This in base: P5TBase 0x7fff6b30fc00 (3)
This in TDerived::F: P8TDerived 0x7fff6b30fbb0 (4)
What is going on here
I have function F in TDerived class, then I send pointer to the function to TBase class: TDerived(): TBase(static_cast<TBase::TFunc>(&TDerived::F)) { and (1) output function pointer.
Then I output function pointer in TDerived class (2) and make TBase class to call the function: `CallF(); (4), (5).
TAnotherBase is here to make different this pointers of TBase and TDerived classes.
So, first question.
I read that function pointers is more like offsets relative to this. If so, why I get the same function pointer values in (1) and (2) - 4197502 ?
Second question
I output this in CallF function (3) and it is all right. But then I call function (this->*Func)(); via this (which is TBase) and in function F this magically becomes completely different this (4)! It changes its type and value! How it is possible? How compiler still remembers that Func (which type is typedef void (TBase::*TFunc)();) is actually from TDerived class? How compiler knows that it should adjust this before sending it to F? Why and how it works?
An example of one way this can be done is described in the Itanium ABI - if you're interested in how the C++ class model can be implemented I highly recommend reading that whole document.
When you convert from a pointer-to-derived-member-function to pointer-to-base-member-function the compiler knows that when you call it this will point to base not derived. So it needs to make sure that the first thing it does is to modify this back from base* to derived*. It can either do this by inventing a shim function which modifies this and jumps to the real function, or by just storing the offset along with the pointer and using it at the call site (which is what the reference above describes). Or I'm sure there are other ways.
(static_cast is not just a compile time operation; quite often it has to do real work at runtime.)
Here is the code:
#include <iostream>
using namespace std;
class T {
public:
virtual int f(int x) { cout << "T::f" << endl; return 0; }
void g() { f(1); cout << "T::g" << endl; }
virtual void h() { g(); cout << "T::h" << endl; }
};
class S: public T {
public:
int f(double y) { cout << "S::f" << endl; return 2; }
virtual void g() { f(1); cout << "S::g" << endl; }
virtual void h() { g(); cout << "S::h" << endl; }
};
int main() {
T t; S s; T * p = &s;
p -> f(1.5);
p -> g();
p -> h();
return 0;
}
I am confused about which functions exactly will be executed, even though I have read about virtual function mechanism in several textbooks. Any help will be highly appreciated.
Update: I have run the code and the output is:
T::f
T::f
T::g
S::f
S::g
S::h
I can't understand how we choose which functions will be executed when we are already inside of a function, for instance.
In your class T will be silently created pointer to virtual table of functions (you can find it exists if you will call sizeof(T), it will be bigger at sizeof(void*) then have to). Your class S will also have such pointer to another virtual table.
Such virtual table have just pointers to functions.
When your class S created, it makes copy of virtual table from T. And then replace pointers to functions defined at T by pointers to functions defined as S. So, it will not replace pointer to function f(), because you don't define it in S, but it will replace pointer to function h(), because you redefined it in S.
So, when you get object with virtual table when first pointer points to T::f(), and second points to S::h(). And you try to operate with that object as with object T.
So, when you call f() - you receive as if T::f() was called.
When you call h() - you receive as if S::h() was called.
Method without "virtual" don't inputs to this table. So, T* will now know about virtual method that was added in child class, and T* will call it's own virtual method if it was not redefined in object.
That is all.
I'm fairly new to C++, and I don't understand what the this pointer does in the following scenario:
void do_something_to_a_foo(Foo *foo_instance);
void Foo::DoSomething()
{
do_something_to_a_foo(this);
}
I grabbed that from someone else's post on here.
What does this point to? I'm confused. The function has no input, so what is this doing?
this refers to the current object.
The keyword this identifies a special type of pointer. Suppose that you create an object named x of class A, and class A has a non-static member function f(). If you call the function x.f(), the keyword this in the body of f() stores the address of x.
The short answer is that this is a special keyword that identifies "this" object - the one on which you are currently operating. The slightly longer, more complex answer is this:
When you have a class, it can have member functions of two types: static and non-static. The non-static member functions must operate on a particular instance of the class, and they need to know where that instance is. To help them, the language defines an implicit variable (i.e. one that is declared automatically for you when it is needed without you having to do anything) which is called this and which will automatically be made to point to the particular instance of the class on which the member function is operating.
Consider this simple example:
#include <iostream>
class A
{
public:
A()
{
std::cout << "A::A: constructed at " << this << std::endl;
}
void SayHello()
{
std::cout << "Hi! I am the instance of A at " << this << std::endl;
}
};
int main(int, char **)
{
A a1;
A a2;
a1.SayHello();
a2.SayHello();
return 0;
}
When you compile and run this, observe that the value of this is different between a1 and a2.
Just some random facts about this to supplement the other answers:
class Foo {
public:
Foo * foo () { return this; }
const Foo * cfoo () const { return this; /* return foo(); is an error */ }
};
Foo x; // can call either x.foo() or x.cfoo()
const Foo y; // can only call x.cfoo()
When the object is const, the type of this becomes a pointer to const.
class Bar {
int x;
int y;
public:
Bar () : x(1), y(2) {}
void bar (int x = 3) {
int y = 4;
std::cout << "x: " << x << std::endl;
std::cout << "this->x: " << this->x << std::endl;
std::cout << "y: " << y << std::endl;
std::cout << "this->y: " << this->y << std::endl;
}
};
The this pointer can be used to access a member that was overshadowed by a function parameter or a local variable.
template <unsigned V>
class Foo {
unsigned v;
public:
Foo () : v(V) { std::cout << "<" << v << ">" << " this: " << this << std::endl; }
};
class Bar : public Foo<1>, public Foo<2>, public Foo<3> {
public:
Bar () { std::cout << "Bar this: " << this << std::endl; }
};
Multiple inheritance will cause the different parents to have different this values. Only the first inherited parent will have the same this value as the derived object.
this is a pointer to self (the object who invoked this).
Suppose you have an object of class Car named car which have a non static method getColor(), the call to this inside getColor() returns the adress of car (the instance of the class).
Static member functions does not have a this pointer(since they are not related to an instance).
this means the object of Foo on which DoSomething() is invoked. I explain it with example
void do_something_to_a_foo(Foo *foo_instance){
foo_instance->printFoo();
}
and our class
class Foo{
string fooName;
public:
Foo(string fName);
void printFoo();
void DoSomething();
};
Foo::Foo(string fName){
fooName = fName;
}
void Foo::printFoo(){
cout<<"the fooName is: "<<fooName<<endl;
}
void Foo::DoSomething(){
do_something_to_a_foo(this);
}
now we instantiate objects like
Foo fooObject("first);
f.DoSomething();//it will prints out first
similarly whatever the string will be passed to Foo constructor will be printed on calling DoSomething().Because for example in DoSomething() of above example "this" means fooObject and in do_something_to_a_foo() fooObject is passed by reference.
Acc. to Object Oriented Programming with c++ by Balaguruswamy
this is a pointer that points to the object for which this function was called. For example, the function call A.max() will set the pointer this to the address of the object. The pointer this is acts as an implicit argument to all the member functions.
You will find a great example of this pointer here. It also helped me to understand the concept.
http://www.learncpp.com/cpp-tutorial/8-8-the-hidden-this-pointer/
Nonstatic member functions such as Foo::DoSomething have an implicit parameter whose value is used for this. The standard specifies this in C++11 §5.2.2/4:
When a function is called, each parameter (8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding argument. [Note: Such initializations are indeterminately sequenced with respect to each other (1.9) — end note ] If the function is a non-static member function, the this parameter of the function (9.3.2) shall be initialized with a pointer to the object of the call, converted as if by an explicit type conversion (5.4).
As a result, you need a Foo object to call DoSomething. That object simply becomes this.
The only difference (and it's trivial) between the this keyword and a normal, explicitly-declared const pointer parameter is that you cannot take the address of this.
It is a local pointer.It refers to the current object as local object