Hi All,

Can anybody help me to assign a base class function pointer in derived class constructor? I have got a compilation error while doing so. Please see the code below:

class Base
{
public:
	void (* fnptr) (void) ;
	void myvurtualfn()
	{
	}  	
};
class Derived:public Base
{
public:
	
	void myvurtualfn1()
	{
	}
	Derived()
	{	
                fnptr =this->myvurtualfn1(); //error C2440: '=' : cannot convert from 'void' to 'void (__cdecl *)(void)'
	}

};

Thanks in Adv,
Je

Dani AI

Generated

A short expert note tying together and : the original compile error came from two distinct issues — calling the member function instead of taking its address, and using the wrong pointer type. A plain function pointer (e.g. void (*)(...)) is not compatible with non‑static member functions because member functions carry an implicit this and require the pointer‑to‑member syntax. The language provides special pointer‑to‑member types and the .* / ->* call operators for that purpose. (cppreference.com)

If the goal is polymorphic behavior, prefer a regular virtual member function and call it through a Base&/Base* — that is the idiomatic, safer solution (also note that virtual dispatch is suppressed during base construction/destruction). If you need a callback stored in Base that derived classes set at construction time, a modern, simpler alternative is std::function (or std::mem_fn) and a small lambda or std::bind that captures this. Example:

#include <functional>

struct Base {
    std::function<void()> fn;
    void call() { if (fn) fn(); }
};

struct Derived : Base {
    Derived() { fn = [this]{ impl(); }; }
    void impl() { /* derived behavior */ }
};

Both approaches are well supported by the standard library and avoid pointer‑to‑member call syntax headaches. See the C++ reference on std::function and on the virtual specifier for details. (cppreference.com)

If you keep the pointer‑to‑member approach, remember the conversion rules and access syntax: the pointer type must match (or be converted explicitly) and you must call it with an object (not as a naked identifier). For full rules and examples consult the pointer‑to‑member section. (cppreference.com)

Recommended Answers

All 4 Replies

>fnptr =this->myvurtualfn1(); //error C2440: '=' : cannot convert from 'void' to 'void (__cdecl *)(void)'

  1. You're not taking the address of the member function, you're calling it.
  2. Pointers to member functions are not compatible with pointers to functions.

might help with the syntax issues.

Hi Naure,
Thanks v much for your help.

I have modified the code as given below. Now the assignment of base class member function pointer is OK. Now I have an another problem in calling the function. it gives compilation error as "error C2065: 'fnptr' : undeclared identifier" Is it possible to call like that? Or is it a syntax error?

class Base
{
public:
    void ( Base :: *fnptr)(void) ;
    void myvurtualfn(void){}  
    Base()
    {
        fnptr = &Base::myvurtualfn;
        (this->*fnptr)();
    }
};

class Derived:public Base
{
public:

    void myvurtualfn(){}
    Derived()
    {
            fnptr = &Base :: myvurtualfn;
    }
};
void myoldfn(Base &b)
{   
    (b.*fnptr)();//error C2065: 'fnptr' : undeclared identifier
}

Thanks in advance,
Jeso

The .* syntax only says what object you're applying the pointer to; you still need to do everything necessary to access the pointer itself:

(b.*b.fnptr)();

In your code, the compiler is looking for fnptr in the unadorned scopes, but fnptr is actually a member of Base, so you need to use the full name of b.fnptr .

Doing the double membership is awkward and can be confusing, so perhaps an intermediate local variable is a better solution:

void (Base::*p)() = b.fnptr;
(b.*p)();

Hi Naure,
My problem has gone.
Thanks very much for your help.

Best regards,
Jeso

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.