Virtual function mechanism - c++

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.

Related

C++ - calling a member function of another class using a pointer

I'm testing, trying to call a member function being passed as a parameter,
the member function has to be one of another class.
this is an example, which gives an error:
"pointer-to-member selection class types are incompatible ("B" and
"A")"
This is the code, what am I doing wrong?
#include <iostream>
using namespace std;
class A {
private:
public:
void fA(int x) {
cout << "hello" << endl;
}
void fB(int x) {
cout << "good bye" << endl;
}
A() {
}
};
class B {
private:
void (A:: * f)(int) = NULL;
public:
B(void (A:: * f)(int)) {
this->f = f;
}
void call() {
(this->*f)(10); //What's wrong here?
}
};
A a = A();
B b = B(&(a.fA));
B b2 = B(&(a.fB));
int main(void) {
b.call();
b2.call();
}
&(a.fA) is not legal C++ syntax. &A::fA is. As you can see, there is no object of type A anywhere of this syntax. &A::fA is just a pointer to a member function, not a pointer-to-member-together-with-an-object combo.
Now in order to call that pointer-to-member, you need an object of class A. In class B, you don't have any. You need to get one in there somehow, and call the function this way:
(a->*f)(10);
where a is a pointer to that object of class A.

Pointers to function member

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.

Why and when is the overload constructor executed?

class A {
public:
A(void) { cout << "A::A" << endl; }
A(const A& a) { cout << "A::A(a)" << endl; }
virtual ~A(void) { cout << "A::~A" << endl; }
virtual void g(void) { cout << "A::g" << endl; }
};
class B : public A {
public:
B(void) { cout << "B::B" << endl; }
~B(void) { cout << "B::~B" << endl; }
void g(void){ cout << "B::g" << endl; }
};
void print(A c) {
cout << "print" << endl;
}
int main(void) {
A a;
B b;
A* c = &b;
c->g();
print(*c);
return 0;
}
I don't understand why this statement A::A(a) get's executed when calling c->g() or print(*c);
And I'm not quite sure to which part of the programm does the Method print belongs to?
Since you pass the argument by value to the print function, a copy must be made using the copy constructor. That is why your copy constructor is called when print is called.
If you change to call be reference (or by passing a pointer) then no copying will be made.
And as stated by others, print is a "normal" function, also known as a "free" function, or a non-member function. It "belongs" to the program, and exist in the global scope and have external linkage.
Print isn't a method, it's a function, as such it doesn't "belong" anywhere - it's simply part of your program.
Functions are from the age before Object-Orientation, though still have an important place.
The void print(A c) Function can be broken down as follows:
void, this is the return value, in this case - nothing.
print(, this is the name of the function.
A c), this means it will take a
single parameter of type A, named c.
As such A::A(const A &) is the copy constructor of the object A; Essentially this method will be called Every time an object of type A is copied into a new object of type A
When you call print(*c), you derefrence The pointer c, this results in a reference to the object pointed to by c (ie: an object of type A). This is then copy constructed into the print function, resulting in a temporary const A & that is used by the function.
This is why the Copy-constructor is called.

Function pointer memory usage

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.

accessing the caller data type in a member function

I want to do something like this code:
myType a;
a->foo();
void foo()
{
cout << a->bar();
}
void bar()
{
cout << a->bar2();
}
void bar2()
{
cout << a->bar3();
}
In another word, when a member function is called, can we use the original caller?
You want:
cout << this->bar();
Or, more simply
cout << bar();
This IBM C++ documentation explains it pretty well. Have a look.
What you're probably trying to do is something like this:
#include <iostream>
class myType {
void foo()
{
std::cout << bar();
}
void bar()
{
std::cout << bar2();
}
void bar2()
{
std::cout << bar3();
}
};
... and in e.g. main method:
int main(int argc, char** argv)
{
myType a;
a->foo();
}
Inside a class, you can refer to methods of the same class just by their name, and they will be called on the same object as the original method! If you want to highlight that you're referring to methods of the same object, use e.g. this->bar() instead of bar(); it is only necessary in cases where there are other names (e.g. method parameters) which would conceal the class members, but it can be used all the time.