C++'da base class'taki function pointer'ı kullanabilme?

Başlatan ucahmetuc, 16 Şubat 2017, 17:24:49

ucahmetuc

Merhaba arkadaşlar. C'den C++'a geçiş sürecindeyim ve önemli bir noktada da takıldım, eventler.

Normalde C'de struct içerisinde tanımladığım fonksiyon göstericisi ile istediğim şeyleri yapıyordum. Ancak C++'da işin içine sınıflar ve kalıtımlar girince durumu çözemedim. Sorunum özetle aşağıdaki gibi.

Bu kodda A'yı ve A.e'yi main'de sorunsuzca kullanabiliyorum. Ancak B'yi A'dan türetmeye çalıştığımda ya da B'nin içerisinde A oluşturup kullanmaya kalktığımda syntax hatası alıyorum.
class A {
public:
	void(*e)();
	void eq(int x, int y){
		if((x==y) && e)
			e();
	}
}

class B : A{
public:
	B(){
		e = event_e;
	}
	void event_e(){};
	void asd(int z){
		eq(5,z);
	}
}

strom

Hocam "void(*e)()" fonksiyon pointer'ına B class'ının static olmayan bir fonksiyonunun adresini bu şekilde atayamazsınız. B classının içerisindeki "void event_e()" aslında "void event_e(B* this)" gibi bir fonksyion ve signature'ı tamamen farklı. Google'da "Member function pointer" şeklinde aratırsanız daha ayrıntılı yanıtlar bulabilirsiniz.

ucahmetuc

#2
Hocam google keyword icin tesekkur ederim. Ben hep "function pointer base class" gibi cumlelerle arama yaptigim icin net bi r sonuca ulasamamistim. Sizin soylediginiz sekilde aratinca soruma cevap olacak bisey bulurum muhtemelen.
İzninizle bir sorum daha olacak. Event icin en mantikli kullanim sekli nasildir? Benim yapmaya calistigimdan daha basit bir yol var midir? Google da arama yaptim ancak daha cok C# daki event'in C++ a implement edilmesi ile ilgili sonuclara ulasabildim. Benim icin -C#daki gibi- bir evente birden cok fonksiyon ekleyebilmenin onemi yok.

Cevaplariniz icin simdiden cok tesekkurler..

yamak

Hocam c++ da C# daki givi delegate event yapısı yok.Bu tarz durumlarda callback fonksiyonlar kullanabilirsin.Callback için ilk olarak aşağıdaki gibi Callback adında bi class oluşturuabilirsin.

callback.h
template<class T1>
class GenericCallback
{
public:
    GenericCallback(){}
    virtual void execute()=0;
};


template<class T1,class T2>
class Callback:public GenericCallback<T2>
{
private:
    T1* pObject;
    void(T1::*pFunc)(void);
public:
    Callback(T1* pObject,void(T1::*pFunc)(void))
    {

        this->pObject=pObject;
        this->pFunc=pFunc;
    }
    void execute()
    {
        (pObject->*pFunc)();
    }
};

Sonra ClassA adında bir class oluşturalım:

classa.h
#include <callback.h>

class ClassA
{
private:
    GenericCallback<ClassA>* callback;
public:
    ClassA();
    void setCallback(GenericCallback<ClassA> &callback);
    void click();
};


classa.cpp
#include "classa.h"

ClassA::ClassA()
{
}

void ClassA::setCallback(GenericCallback<ClassA> &callback)
{
    this->callback=&callback;
}

void ClassA::click()
{
    callback->execute();
}

ClassA yı bir buton gibi düşünebilirsin.Tıklandığında callback ile dönüş yapmasını istiyoruz.Event gibi...
Şİmdi de ClassA ya tıklayacak olan ClassB yi yazalım.
classb.h
#include <classa.h>
#include <iostream>

using namespace std;
class ClassB
{
public:
    ClassB();
    ClassA instanceA;
    Callback<ClassB,ClassA> bCallback;
    void clickToClassA();
    void clicked();
};


classb.cpp
#include "classb.h"

ClassB::ClassB():bCallback(this,&ClassB::clicked)
{
    instanceA.setCallback(this->bCallback);
}

void ClassB::clicked()
{
    cout<<"Clicked"<<endl;
}

void ClassB::clickToClassA()
{
    instanceA.click();
}

Bu class'ta da clickToClassA fonksiyonunu mouse ile tıklama gibi düşünebilirsin.clicked fonksiyonu da bizim callback imiz.Tıklandığında çağıralacak ve konsola "Clicked" yazacak.
Bu da main.cpp
#include <iostream>
#include <classb.h>
using namespace std;

int main(int argc, char *argv[])
{
    ClassB instanceB;
    instanceB.clickToClassA();
}

Hocam, hiç bunlarla uğraşmayayım diyorsan Qt kullanabilrsin.Qt nin kendine has signal slot yapısı var.

ucahmetuc

@yamak ve @strom hocalarım tekrardan teşekkürler. Sizlerin paylaştıklarını müsait bi zamanımda inceleyip atıcam hafızaya :D
Bu arada 32bit MCU'larda C değil de C++'ı -bilinçli bir şekilde- kullanabilmek istediğim için C++'ı çözmeye çalışıyorum...

Bu arada member function pointer'la alakalı şöyle makale tadında bir paylaşım var. benim gibi olayı tam anlamamış kişilerin göz gezdirmesini tavsiye ederim. ben de daha tamamını okuyamadım: https://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible