Pointer to protected member function from derived class

D

Dmitry

Hi all,

Consider the following code:
class A {
public:
A() {}
void DoMethod() { (this->*m_pMethod)(); }

protected:
virtual void MethodA() { ... }
virtual void MethodB() { ... }
void (A::*m_pMethod)();

};

class B1 : public A {
public:
B1() { m_pMethod = &A::MethodA; } // invokes B1::MethodA()
protected:
virtual void MethodA() { ... }

};

Class A has a member m_pMethod, which is pointer to a class member
function. This function can be over ridden by derived class (in my
example this is what B1 does). There more B2....Bn in the system.

This code was fine under gcc 3.2.3 but not ok under 4.1.2:
test.cc: In constructor 'B1::B1()':
test.cc:9: error: 'virtual void A::MethodA()' is protected
test.cc:17: error: within this context

Ok, after some googling I found it's related to gcc 3.4 changes -
http://www.gnu.org/software/gcc/gcc-3.4/changes.html#3.4.6 (look for
"forming a pointer to member or a pointer to member function").

Setting B1() { m_pMethod = &B1::MethodA; } does not help too:
test.cc: In constructor 'B1::B1()':
test.cc:17: error: cannot convert 'void (B1::*)()' to 'void (A::*)()'
in assignment

Any ideas how to fix it?

BR
Dima
 
B

Bo Persson

Dmitry said:
Hi all,

Consider the following code:
class A {
public:
A() {}
void DoMethod() { (this->*m_pMethod)(); }

protected:
virtual void MethodA() { ... }
virtual void MethodB() { ... }
void (A::*m_pMethod)();

};

class B1 : public A {
public:
B1() { m_pMethod = &A::MethodA; } // invokes B1::MethodA()
protected:
virtual void MethodA() { ... }

};

Class A has a member m_pMethod, which is pointer to a class member
function. This function can be over ridden by derived class (in my
example this is what B1 does). There more B2....Bn in the system.

This code was fine under gcc 3.2.3 but not ok under 4.1.2:
test.cc: In constructor 'B1::B1()':
test.cc:9: error: 'virtual void A::MethodA()' is protected
test.cc:17: error: within this context

Ok, after some googling I found it's related to gcc 3.4 changes -
http://www.gnu.org/software/gcc/gcc-3.4/changes.html#3.4.6 (look for
"forming a pointer to member or a pointer to member function").

Other compilers agree with this. You can only take the address of
protected members of the base class, not of any other A's.
Setting B1() { m_pMethod = &B1::MethodA; } does not help too:
test.cc: In constructor 'B1::B1()':
test.cc:17: error: cannot convert 'void (B1::*)()' to 'void
(A::*)()' in assignment

It helps in that it takes the address of a function. Just not the
right one. :)
Any ideas how to fix it?

Why is B1 setting a variable in A? Can you move that to a member
function of A (and make the pointer private)?
class A {
public:
A() {}
void DoMethod() { (this->*m_pMethod)(); }

protected:
virtual void MethodA() { ... }
virtual void MethodB() { ... }

void SelectMethodA()
{ m_pMethod = &A::MethodA; }

private:
void (A::*m_pMethod)();

};

class B1 : public A {
public:

B1() { SelectMethodA(); }
protected:
virtual void MethodA() { ... }

};

Bo Persson
 
J

James Kanze

Consider the following code:
class A {
public:
A() {}
void DoMethod() { (this->*m_pMethod)(); }
protected:
virtual void MethodA() { ... }
virtual void MethodB() { ... }
void (A::*m_pMethod)();
};
class B1 : public A {
public:
B1() { m_pMethod = &A::MethodA; } // invokes B1::MethodA()
protected:
virtual void MethodA() { ... }
};
Class A has a member m_pMethod, which is pointer to a class
member function. This function can be over ridden by derived
class (in my example this is what B1 does). There more
B2....Bn in the system.
This code was fine under gcc 3.2.3 but not ok under 4.1.2:
test.cc: In constructor 'B1::B1()':
test.cc:9: error: 'virtual void A::MethodA()' is protected
test.cc:17: error: within this context
Ok, after some googling I found it's related to gcc 3.4 changes -http://www.gnu.org/software/gcc/gcc-3.4/changes.html#3.4.6(look for
"forming a pointer to member or a pointer to member function").
Setting B1() { m_pMethod = &B1::MethodA; } does not help too:
test.cc: In constructor 'B1::B1()':
test.cc:17: error: cannot convert 'void (B1::*)()' to 'void (A::*)()'
in assignment
Any ideas how to fix it?

Make the functions public. (I find almost no use for protected
anyway, except in closed hierarchies, and then, it's almost
always for data, and not functions.)

Provide a protected function in A which returns the desired
pointer to member. (Note that it cannot be a static function,
even though you don't access any members of the object, or
you'll run into the same problem. I think.) Or provide a
protected function which sets the member pointer to function to
the desired value.

Provide an additional virtual function in A which is overloaded
in the derived class to dispatch to whichever function is
desired.

Provide a helper object (possibly friend) in A which calls the
desired fucntion and which can be instantiated in B.
 

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,962
Messages
2,570,134
Members
46,692
Latest member
JenniferTi

Latest Threads

Top