function pointer and virtual function - c++

I guess my question should be silly but it is true that I have never seen a function pointer that is declared as virtual. Is there a reason for this?
Edit:
I should have said: Is it possible that the function it points to is specified as virtual?

Well, yes (and no).
Ordinary function pointers cannot point to non-static member functions. They can only point to standalone functions, which is why for ordinary function pointers the matter of function virtuality does not even come into the picture.
In order to point to member functions in C++ you need a pointer of special kind: one that has pointer-to-member-function type. A pointer of this type can point to non-virtual member functions as well and to virtual member functions. There are no special steps to take if you want to point to virtual member function. For example
struct B {
virtual void foo() {}
void bar() {}
};
...
B b;
void (B::*pfunc)(); // declare a pointer to a member function
pfunc = &B::foo; // make it point to `B::foo`
(b.*pfunc)(); // calls `B::foo` for object `b`
pfunc = &B::bar; // make it point to `B::bar`
(b.*pfunc)(); // calls `B::bar` for object `b`
However, when you make such pointer to point to a virtual member function, you have to keep in mind that it is does not really get tied to a specific version of that function in the class hierarchy. The decision about the specific function to call is made at the point of the call. For example
// given the above `B`
struct D : B {
virtual void foo() {}
};
...
void (B::*pfoo)(); // declare a pointer to a member function
pfoo = &B::foo; // and make it point to `B::foo`
In the above example we made out pointer pfoo to point to B::foo. Or did we? In reality the pointer is not hard-linked to B::foo specifically. These two calls
B b;
D d;
(b.*pfoo)();
(d.*pfoo)();
will call two different functions. The first one will call B::foo for object b, while the second one will call D::foo for object d, even though we used the same pointer value in both cases. This makes sense actually in many applications.
Yet, in some low-level situation it would be useful to have a pointer that is hard-tied to a specific version of virtual function. I.e. it would be nice to have a pointer that would call B::foo for B subobject of object d when we do
(d.*pfoo)();
To achieve that we need to be able to specify whether we want to bind it early (at the point of initialization) or late (at the point of the call). Unfortunately, C++ language provides no such functionality.

A Function pointer is just a pointer to the function. It just stores address of an function just like any pointer to a type stores address of an type.
keyword virtual is used to implement polymorphic behavior(between functions of base class and derived class)through dynamic dispatch.
Given the above two are distinctly different and the idea of a function pointer to be virtual makes no sense at all.
whether the function it points to is specified as virtual ?
As I mentioned before an function pointer just stores address of an function. It is just an type. For eg:
int *i = NULL;
void doSomething();
typedef void(*ptr)() = NULL;
ptr = &doSomething();
In above example:
i is a type of int *. Similarly,
ptr is a type which can store address of an function which takes no parameter and returns no parameter.
So Yes, fundamentally, you can make the function to which a function pointer points as virtual, just like you would make any function virtual by declaring the particular function as virtual in the class.
The function pointer being a type can point to any function with that prototype, while declaring a function as virtual means having dynamic dispatch enabled on a particular function, as you see both are not the same.

Virtuality is a property of member functions. If you have a pointer to a virtual member function then a virtual call will be made automatically. Regular functions can't be virtual, so a virtual function pointer makes no sense. In either case there's no point making a function pointer virtual as its the function being pointed to that counts.

Related

Does a VTBL contains pointers to non-virtual functions? [duplicate]

This question already has answers here:
In C++, is a function automatically virtual if it overrides a virtual function?
(4 answers)
Closed 5 years ago.
I'm having hard time to understand why the code below print C::f2 instead of B::f2.
From Charles Bailey answer:
When a non-virtual function is called the implementation must use the
static type of the object on which the function is being called to
determine the correct function to call. A function stored in a vtable
accessed by a vptr will be dependent on the dynamic type of the
object, not any static type of a reference or pointer through which it
is being accessed.
I'm a bit lost, Inside A::f1 there is a call to f2. How does the compiler know which method to call?
My assemption:
The compiler somehow remmber that we are inside object of type C.
The compiler check if C contain a non virtual method name f2.
a. if yes, run it.
b. use the object's pointer to access his vtbl and run the right f2.
Am I right?
struct A
{
void f1()
{
f2();
}
virtual void f2()
{
cout<<"A::f2"<<endl;
}
};
struct B:public A
{
virtual void f2()
{
cout<<"B::f2"<<endl;
}
};
struct C:public B
{
void f2()
{
cout<<"C::f2"<<endl;
}
};
int main()
{
C c1;
c1.f1();
return 0;
}
Every member function has an implicit this parameter. The static type of this inside f1 is always A * const. This is true for any member function. The static type of the implicit object parameter is the enclosing class where the function is defined.
The call inside f1 is resolved as this->f2(). Since this is a call via pointer, the function f2 is dispatched dynamically. This is despite the fact the f1 is not virtual, and will always be called by static dispatch.
By whatever mechanism the compiler uses (a VTable is an implementation detail, not mandated by the C++ standard itself), we get a call to C::f2.
So your assumptions need some revision, I'd say.
To answer your question as you specified in the comments. C::f2 is virtual. You may have omitted the virtual specifier when overriding it, but there is no "unvirtualising" it.

c++ virtual function call without pointer or reference

As far as I know, virtual function call usually requires pointer or reference. So I am very surprised by the following codes.
#include <iostream>
using namespace std;
class B{
public:
void runB(){ call(); }
virtual void call(){ cout<<"B\n"; };
};
class D: public B{
public:
void runD(){ runB(); }
void call(){ cout<<"D\n"; }
};
int main(){
D d;
d.runD();
}
The output is
D
Could someone please comment why this virtual function call works? Thanks。
Within a member function, any references to other member functions or variables are implicitly resolved via the this pointer. So in the definition of runB(), the call() really means this->call(). The virtual function call is performed using the current object's virtual table.
Firstly, virtual function call does not require a pointer or a reference. As far as the language is concerned, any call to virtual function is a virtual call, unless you explicitly suppress the virtual dispatch mechanism by using a qualified function name. For example, these
d.D::call(); // calls `D::call()` directly
d.B::call(); // calls `B::call()` directly
are calls which were explicitly forced to be non-virtual. However, this
d.call(); // calls `D::call()` virtually
is a virtual call. In this case it is immediately obvious to the compiler that the target function is D::call(), so the compiler normally optimizes this virtual call into a regular direct call. Yet, conceptually, d.call() is still a virtual call.
Secondly, the call to call() made inside B::runB() is made through a pointer. The pointer is present there implicitly. Writing call() inside B::runB() is just a shorthand for (*this).call(). this is a pointer. So that call is made through a pointer.
Thirdly, the key property of virtual call is that the target function is chosen in accordance with the dynamic type of the object used in the call. In your case, even when you are inside B::runB() the dynamic type of the object *this is D. Which is why it calls D::call(), as it should.
Fourthly, what you really need a pointer or a reference for is to observe the actual polymorphism. Polymorphism proper occurs when static type of the object expression used in the call is different from its dynamic type. For that you do indeed need a pointer or a reference. And that is exactly what you observe in that (*this).call() call inside B::runB(). Even though the static type of *this is B, its dynamic type is D and the call is dispatched to D::call().
The difference between virtual to not virtual is:
not virtual - always goes by the caller object/reference/pointer type.
virtual - reference/pointer - goes by the created object type.
virtual - object - goes by the caller.
for example:
class A{
public:
virtual void f(){
cout <<"A\n";
}
};
class B: public A{
public:
virtual void f(){
cout <<"B\n";
}
};
B b;
A a,*pa=&b;
a.f(); //A: caller type = created type - same for not virtual
b.f(); //B: caller type = created type - same for not virtual
((A)b).f(); //A: object goes by the caller type - same for not virtual
pa->f(); // B: pointer goes by the created type - it would be A if it was not virtual!!

Why is a virtual table required only in case of virtual functions?

From http://www.learncpp.com/cpp-tutorial/125-the-virtual-table/, code such as
class Base
{
public:
virtual void function1() {};
virtual void function2() {};
};
class D1: public Base
{
public:
virtual void function1() {};
};
class D2: public Base
{
public:
virtual void function2() {};
};
generates a virtual table similar to http://www.learncpp.com/images/CppTutorial/Section12/VTable.gif:
The virtual table as above makes sense. After all the objects need a way to call functions, and need to use function pointers to find them.
What I do not understand is why this is only required in case of using virtual functions? I am definitely missing something since a virtual table does not directly depend on virtual functions.
As an example, if the code being used were
class Base
{
public:
void function1() {};
void function2() {};
};
...
Base b;
b.function1();
and there is no virtual table (meaning there is no pointer to where the function resides), how would the b.function1() call resolve?
Or is it that we have a table in this case as well, just that it is not called a virtual table? In that case the question would arise as to why we need a new kind of table for virtual functions?
[If] there is no virtual table (meaning there is no pointer to where the function resides), how would the b.function1() call resolve?
There is a "pointer", inside the compiler as it's parsing and analysing your code. The compiler's the thing that decides where the function will be generated, so it knows how calls to said function should resolve. In concert with the linker, this all happens tidily within the build process.
The only reason that this doesn't work for virtual functions is that which function you call depends on a type known only at runtime; in fact the same function pointers are present verbatim in the virtual table, written there by the compiler. It's just that in this case, there are multiple to choose from, and they cannot be chosen from until long (read: potentially months or even years!) after the compiler ceases to be involved at all.
There's already a good answer, but I'll attempt a slightly simpler (albeit longer) one:
Think of a non-virtual method of the form
class A
{
public:
int fn(int arg1);
};
as equivalent to a free function of the form:
int fn(A* me, int arg1); // overload A
where me corresponds to the this pointer inside the method version.
If you now have a subclass:
class B : public A
{
public:
int fn(int arg1);
};
this is equivalent to a free function like this:
int fn(B* me, int arg1); // overload B
Note that the first argument has a different type to the free function we declared earlier - the function is overloaded on the type of the first argument.
If you now have some code calling fn() it will choose the overload based on the static type (compile time type) of the first argument:
A* p;
B* q;
// ...
// assign valid pointer values to p and q
// ...
int a = fn(p, 0); // will call overload A
int b = fn(q, 0); // will call overload B
The compiler can and will determine the function to call at compile time in each case and can emit assembly code with a fixed function address or address offset. The concept of a runtime virtual table is nonsensical here.
Now, when I said to think of the method version as equivalent to the free function version, you'll find that at the assembly language level, they are equivalent. The only difference will be the so-called mangled name that encodes the type in the compiled function name and distinguishes overloaded functions. The fact that you call methods via p->fn(0), that is, with the first argument before the method name is pure syntactic sugar - you're not actually dereferencing the pointer p in the example, even though it looks like it. You're just passing p as the implicit this argument. So, to continue the above example,
p->fn(0); // will always call A::fn()
q->fn(0); // will always call B::fn()
because fn being a non-virtual method means the compiler dispatches on the this pointer's static type, which it can do at compile time.
Although virtual functions use the same calling syntax as non-virtual member functions, you are in fact dereferencing the object pointer; specifically, you're dereferencing the pointer to the object's class's virtual table.

Is a pointer to a virtual member function valid in the constructor of the base class?

My question is not about calling a virtual member function from a base class constructor, but whether the pointer to a virtual member function is valid in the base class constructor.
Given the following
class A
{
void (A::*m_pMember)();
public:
A() :
m_pMember(&A::vmember)
{
}
virtual void vmember()
{
printf("In A::vmember()\n");
}
void test()
{
(this->*m_pMember)();
}
};
class B : public A
{
public:
virtual void vmember()
{
printf("In B::vmember()\n");
}
};
int main()
{
B b;
b.test();
return 0;
}
Will this produce "In B::vmember()" for all compliant c++ compilers?
The pointer is valid, however you have to keep in mind that when a virtual function is invoked through a pointer it is always resolved in accordance with the dynamic type of the object used on the left-hand side. This means that when you invoke a virtual function from the constructor, it doesn't matter whether you invoke it directly or whether you invoke it through a pointer. In both cases the call will resolve to the type whose constructor is currently working. That's how virtual functions work, when you invoke them during object construction (or destruction).
Note also that pointers to member functions are generally not attached to specific functions at the point of initalization. If the target function is non-virtual, they one can say that the pointer points to a specific function. However, if the target function is virtual, there's no way to say where the pointer is pointing to. For example, the language specification explicitly states that when you compare (for equality) two pointers that happen to point to virtual functions, the result is unspecified.
"Valid" is a specific term when applied to pointers. Data pointers are valid when they point to an object or NULL; function pointers are valid when they point to a function or NULL, and pointers to members are valid when the point to a member or NULL.
However, from your question about actual output, I can infer that you wanted to ask something else. Let's look at your vmember function - or should I say functions? Obviously there are two function bodies. You could have made only the derived one virtual, so that too confirms that there are really two vmember functions, who both happen to be virtual.
Now, the question becomes whether when taking the address of a member function already chooses the actual function. Your implementations show that they don't, and that this only happens when the pointer is actually dereferenced.
The reason it must work this way is trivial. Taking the address of a member function does not involve an actual object, something that would be needed to resolve the virtual call. Let me show you:
namespace {
void (A::*test)() = &A::vmember;
A a;
B b;
(a.*test)();
(b.*test)();
}
When we initialize test, there is no object of type A or B at all, yet is it possible to take the address of &A::vmember. That same member pointer can then be used with two different objects. What could this produce but "In A::vmember()\n" and "In B::vmember()\n" ?
Read this article for an in-depth discussion of member function pointers and how to use them. This should answer all your questions.
I have found a little explanation on the Old New Thing (a blog by Raymond Chen, sometimes referred to as Microsoft's Chuck Norris).
Of course it says nothing about the compliance, but it explains why:
B b;
b.A::vmember(); // [1]
(b.*&A::vmember)(); // [2]
1 and 2 actually invoke a different function... which is quite surprising, really. It also means that you can't actually prevent the runtime dispatch using a pointer to member function :/
I think no. Pointer to virtual member function is resolved via VMT, so the same way as call to this function would happen. It means that it is not valid, since VMT is populated after constructor finished.
IMO it is implementation defined to take address of a virtual function. This is because virtual functions are implemented using vtables which are compiler implementation specific. Since the vtable is not guaranteed to be complete until the execution of the class ctor is done, a pointer to an entry in such a table (virtual function) may be implementation defined behavior.
There is a somewhat related question that I asked on SO here few months back; which basically says taking address of the virtual function is not specified in the C++ standard.
So, in any case even if it works for you, the solution will not be portable.

Calling base class definition of virtual member function with function pointer

I want to call the base class implementation of a virtual function using a member function pointer.
class Base {
public:
virtual void func() { cout << "base" << endl; }
};
class Derived: public Base {
public:
void func() { cout << "derived" << endl; }
void callFunc()
{
void (Base::*fp)() = &Base::func;
(this->*fp)(); // Derived::func will be called.
// In my application I store the pointer for later use,
// so I can't simply do Base::func().
}
};
In the code above the derived class implementation of func will be called from callFunc. Is there a way I can save a member function pointer that points to Base::func, or will I have to use using in some way?
In my actual application I use boost::bind to create a boost::function object in callFunc which I later use to call func from another part of my program. So if boost::bind or boost::function have some way of getting around this problem that would also help.
When you call a virtual method via a reference or a pointer you will always activate the virtual call mechanism that finds the most derived type.
Your best bet is to add an alternative function that is not virtual.
What you're trying to do unfortunately isn't possible. Pointer-to-member-functions are designed to maintain the virtualness of the function pointed-to.
Your problem is that a member function pointer is not quite the same as a bare function pointer. It actually isn't just a pointer, but a considerably more complex structure, which varies in its details at the level of the compiler implementation. When you invoke it via the syntax (this->*fp)() you are actually calling it on the original object, which causes virtual function dispatch.
One thing that might work is to cast it to a non-method pointer type. This is a little creaky but I think it should work. You still need to pass a Base * but you do it explicitly and the virtual function dispatch is by-passed:
typedef void BasePointer(Base*);
void callFunc()
{
BasePointer fp = (BasePointer *)&Base::func;
fp(this);
}
Update: Ok, no, you can't do it that way. It's illegal, and wouldn't be safe it if it was legal. The C++ FAQ has more on this. But knowing that doesn't solve your problem. The issue is that, pointer-to-object or pointer-to-member if you want to call Base::func through a Base pointer, the object it is pointing must also be a Base. If you can arrange that, then you can use a member function pointer.
Here's another thought, not pretty, but at least workable. Provide a function in Derived, non-virtual, that explicitly calls Base::func. Point to that instead. It won't scale if you need to do this in the general case of lots of different variants of func and callFunc but it will work fine for one method.
Is there any specific reason for doing this via a function pointer?
You should be able to just write:
Base::func();
to call the base class implementation.
In addition to what quark says, a more general remark is that you should use a signal/slot implementation rather than a bare function pointer. Boost has one, there's libsigc and a bunch of others.
What's wrong with this?
(Base(*this).*fp)();
Now if you're satisfied with that, it raises the question of why you're even using a function pointer in the first place. I think some more context might help.