Can't Invoke Member Function Pointer -- Must Static_Cast

I

Immortal Nephi

Please look at the line with "// Error" in main() body. I define
Bottom class. I set Center1 pointer and Center2 pointer to Bottom
class without any problem. I can't use either Center1 pointer or
Center2 pointer to invoke member function pointer.

class Bottom;

class Top
{
public:

Top();
~Top();

void Run();

void (Bottom::*Run_PTR)();
};

class Center1 : virtual public Top
{
public:

Center1();
~Center1();

void Run();
};

class Center2 : virtual public Top
{
public:

Center2();
~Center2();

void Run();
};

class Bottom : public Center1, public Center2
{
public:

Bottom();
~Bottom();

void Run();
};

Top::Top()
{
cout << "Top()\n";
}

Top::~Top()
{
cout << "~Top()\n";
}

void Top::Run()
{
cout << "Top::Run()\n";
}

Center1::Center1()
{
cout << "Center1()\n";
}

Center1::~Center1()
{
cout << "~Center1()\n";
}

void Center1::Run()
{
cout << "Center1::Run()\n";
Run_PTR = &Center2::Run;
}

Center2::Center2()
{
cout << "Center2()\n";
}

Center2::~Center2()
{
cout << "~Center2()\n";
}

void Center2::Run()
{
cout << "Center2::Run()\n";
Run_PTR = &Center1::Run;
}

Bottom::Bottom()
{
cout << "Bottom()\n";
}

Bottom::~Bottom()
{
cout << "~Bottom()\n";
}

void Bottom::Run()
{
cout << "Bottom::Run()\n";
}

int main()
{
Bottom b;
Center1* C1_PTR = &b;
Center2* C2_PTR = &b;

C1_PTR->Run(); // OK
C2_PTR->Run(); // OK

b.Run_PTR = &Center1::Run;

(C1_PTR->*(C1_PTR->Run_PTR))(); // Error

(b.*(b.Run_PTR))(); // OK
(b.*(b.Run_PTR))(); // OK
(b.*(b.Run_PTR))(); // OK



system("pause");

return 0;
}
 
V

Victor Bazarov

Immortal said:
Please look at the line with "// Error" in main() body. I define
Bottom class. I set Center1 pointer and Center2 pointer to Bottom
class without any problem. I can't use either Center1 pointer or
Center2 pointer to invoke member function pointer.

Doesn't that require a non-existing implicit conversion from a base
class to a derived class? Since 'Run_PTR' is a member of 'Bottom', the
object for which you're invoking it has to be of the type 'Bottom'. You
have a pointer to 'Center1', which is a base class for 'Bottom'. You
should be able to invoke your 'Run_PTR' function if you do 'static_cast'
like so

(static_cast<Bottom*>(C1_PTR)->*(C1_PTR->Run_PTR))();

(I didn't check, but you get the idea).
class Bottom;

class Top
{
public:

Top();
~Top();

void Run();

void (Bottom::*Run_PTR)();
};

class Center1 : virtual public Top
{
public:

Center1();
~Center1();

void Run();
};

class Center2 : virtual public Top
{
public:

Center2();
~Center2();

void Run();
};

class Bottom : public Center1, public Center2
{
public:

Bottom();
~Bottom();

void Run();
};

Top::Top()
{
cout << "Top()\n";
}

Top::~Top()
{
cout << "~Top()\n";
}

void Top::Run()
{
cout << "Top::Run()\n";
}

Center1::Center1()
{
cout << "Center1()\n";
}

Center1::~Center1()
{
cout << "~Center1()\n";
}

void Center1::Run()
{
cout << "Center1::Run()\n";
Run_PTR = &Center2::Run;
}

Center2::Center2()
{
cout << "Center2()\n";
}

Center2::~Center2()
{
cout << "~Center2()\n";
}

void Center2::Run()
{
cout << "Center2::Run()\n";
Run_PTR = &Center1::Run;
}

Bottom::Bottom()
{
cout << "Bottom()\n";
}

Bottom::~Bottom()
{
cout << "~Bottom()\n";
}

void Bottom::Run()
{
cout << "Bottom::Run()\n";
}

int main()
{
Bottom b;
Center1* C1_PTR = &b;
Center2* C2_PTR = &b;

C1_PTR->Run(); // OK
C2_PTR->Run(); // OK

b.Run_PTR = &Center1::Run;

(C1_PTR->*(C1_PTR->Run_PTR))(); // Error

(b.*(b.Run_PTR))(); // OK
(b.*(b.Run_PTR))(); // OK
(b.*(b.Run_PTR))(); // OK



system("pause");

return 0;
}

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,069
Latest member
SimplyleanKetoReviews

Latest Threads

Top