Page 1 of 1

Pointer la o functie membru trimis ca argument

Posted: 03 Aug 2007, 11:53
by crystyce
Salut,

Incerc sa trimit ca parametru intr-o functie un pointer la o functie membra a unei clase.
Problema mea e urmatoarea:

Am 2 clase X si Y si 2 functii : bool X.f1(CListCtrl &) si Y.f2(bool (X::*f1)(CListCtrl&)) .
f2 primeste ca parametru un pointer la o functie membru din clasa X.

Y test;
bool (X::*ptrFunc)(CListCtrl&) = &(X::f1);

test.f2(ptrFunc);

Ultima linie genereaza eroare de compilare :
error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject'

Compilatorul MSVC 8, si clasa Y este derivata din CDialog; De fapt e ceva de genu Y -> XDialog ->ZDialog -> CDialog
Prima oara am crezut ca are legatura cu constructorii lui Y dar clasa imi compileaza, eroarea apare numai cand incerc sa apelez functia...
Ma gandesc ca sunt de vina constructorii claselor parinte ale lui X dar astea nu au la baza CObject...

Re: Pointer la o functie membru trimis ca argument

Posted: 03 Aug 2007, 19:25
by Sanda X
Pune te rog exemplu de cod real.

Re: Pointer la o functie membru trimis ca argument

Posted: 05 Aug 2007, 17:25
by Ovidiu Cucu
Hai sa incerc sa descalcesc putin problema si sa-i dau un sens, un tel final.
Deci...
Sa zicem ca avem o clasa X cu mai multe functii care intorc bool si primesc un argument tip CListCtrl&.
Definitia clasei X ar arata cam asa:

Code: Select all

// X.h
class X
{
public:
   bool f1(CListCtrl& list);
   bool f2(CListCtrl& list);
   // ...
   bool fn(CListCtrl& list);
};
iar implementarea ei

Code: Select all

// X.cpp
bool X::f1(CListCtrl& list)
{
   TRACE0("\n X::f1");
   bool bRet = false;
   // ... do something with the list.
   return bRet;
}
bool X::f2(CListCtrl& list)
{
   TRACE0("\n X::f2");
   bool bRet = false;
   // ... do something else with the list.
   return bRet;
}
// ...
bool X::fn(CListCtrl& list)
{
   TRACE0("\n X::fn");
   bool bRet = false;
   // ... do anything else with the list.
   return bRet;
}
In continuare, am o clasa Y derivata din CDialog cu un membru tip CListCtrl (sa-i zicem m_list).
Vreau ca in clasa Y sa implementez o metoda caruia sa-i transmit (sa zicem, in functie de o conditie) un pointer la functia membru X::f1, X::f2,... sau X::fn in asa fel incat sa efectuez o operatie specifica cu acel m_list.
Deci, dupa ce mai definesc si un tip pointer la functie membru in clasa X, care... blah-blah (vezi mai jos pfnX), pentru usurinta scrierii, citirii si evitarea erorilor, clasa Y ar arata cam asa

Code: Select all

// Y.h
#include "X.h"

typedef bool (X::*pfnX)(CListCtrl&);

class Y : public CDialog
{
protected:
   CListCtrl m_list;
public:
   void f(pfnX pfn)
   {
      X x;
      bool bRet = (x.*pfn)(m_list);
   }
// ...
};
A mai ramas si de utilizat acea minunata functie buna de prins urechile copiilor la interviu.
Ca de exemplu:

Code: Select all

// Y.cpp
void Y::OnSomeTestButton()
{
   // just for testing purpose
   f(&X::f1); // pass a pointer to X::f1
   f(&X::f2); // pass a pointer to X::f2
   // ...
   f(&X::fn); // pass a pointer to X::fn
}
Pana acum... nici o eroare si totul merge perfect.

Sper ca e destul de clar exemplul meu si ca e cat de cat pe aproape la ceea ce vrei tu sa faci.
Daca nu, te rog si eu ca si Sanda,... putin cod nu strica.

Re: Pointer la o functie membru trimis ca argument

Posted: 26 Mar 2015, 15:43
by Woolmer
O metoda ar fi sa hanluiesti WM_DRAWITEM in dialogul parinte, dar un pic si mai bine este e sa derivezi din CButton si sa suprascrii functia virtuala CButton::DrawItem.

Re: Pointer la o functie membru trimis ca argument

Posted: 22 Jun 2017, 09:33
by mesajflaviu
Ovidiu Cucu wrote:Hai sa incerc sa descalcesc putin problema si sa-i dau un sens, un tel final.
Deci...
Sa zicem ca avem o clasa X cu mai multe functii care intorc bool si primesc un argument tip CListCtrl&.
Definitia clasei X ar arata cam asa:

Code: Select all

// X.h
class X
{
public:
   bool f1(CListCtrl& list);
   bool f2(CListCtrl& list);
   // ...
   bool fn(CListCtrl& list);
};
iar implementarea ei

Code: Select all

// X.cpp
bool X::f1(CListCtrl& list)
{
   TRACE0("\n X::f1");
   bool bRet = false;
   // ... do something with the list.
   return bRet;
}
bool X::f2(CListCtrl& list)
{
   TRACE0("\n X::f2");
   bool bRet = false;
   // ... do something else with the list.
   return bRet;
}
// ...
bool X::fn(CListCtrl& list)
{
   TRACE0("\n X::fn");
   bool bRet = false;
   // ... do anything else with the list.
   return bRet;
}
In continuare, am o clasa Y derivata din CDialog cu un membru tip CListCtrl (sa-i zicem m_list).
Vreau ca in clasa Y sa implementez o metoda caruia sa-i transmit (sa zicem, in functie de o conditie) un pointer la functia membru X::f1, X::f2,... sau X::fn in asa fel incat sa efectuez o operatie specifica cu acel m_list.
Deci, dupa ce mai definesc si un tip pointer la functie membru in clasa X, care... blah-blah (vezi mai jos pfnX), pentru usurinta scrierii, citirii si evitarea erorilor, clasa Y ar arata cam asa

Code: Select all

// Y.h
#include "X.h"

typedef bool (X::*pfnX)(CListCtrl&);

class Y : public CDialog
{
protected:
   CListCtrl m_list;
public:
   void f(pfnX pfn)
   {
      X x;
      bool bRet = (x.*pfn)(m_list);
   }
// ...
};
A mai ramas si de utilizat acea minunata functie buna de prins urechile copiilor la interviu.
Ca de exemplu:

Code: Select all

// Y.cpp
void Y::OnSomeTestButton()
{
   // just for testing purpose
   f(&X::f1); // pass a pointer to X::f1
   f(&X::f2); // pass a pointer to X::f2
   // ...
   f(&X::fn); // pass a pointer to X::fn
}
Pana acum... nici o eroare si totul merge perfect.

Sper ca e destul de clar exemplul meu si ca e cat de cat pe aproape la ceea ce vrei tu sa faci.
Daca nu, te rog si eu ca si Sanda,... putin cod nu strica.
Ovidiu, exemplul asta e mult mai explicativ (simplu si clar) decat multe altele de pe internet !