İşlev işaretlerini kullanmanın yanlış bir tarafı yoktur. Bununla birlikte, statik olmayan üye işlevlere işaretçiler normal işlev işaretçilerine benzemez: üye işlevlerin, işleve örtük bir argüman olarak iletilen bir nesnede çağrılması gerekir. Yukarıdaki üye işlevinizin imzası, bu nedenle
void (aClass::*)(int, int)
kullanmaya çalıştığınız tip yerine
void (*)(int, int)
Bir yaklaşım, üye işlevini yapmaktan oluşabilir, static
bu durumda herhangi bir nesnenin çağrılmasını gerektirmez ve türle birlikte kullanabilirsiniz void (*)(int, int)
.
Eğer sınıfın herhangi statik olmayan üyesine erişmek gerekiyorsa ve siz işlevi C arayüzünün bir parçası olduğu için, örneğin işlev işaretçileri ile sopa gerekir, en iyi seçenek her zaman geçmektir void*
işlev işaretçileri ve çağrı alarak fonksiyonunuza üyeniz, öğesinden bir nesne alan void*
ve ardından üye işlevini çağıran bir yönlendirme işlevi aracılığıyla .
Uygun bir C ++ arabiriminde, işlev nesnelerinin rastgele sınıf türlerini kullanması için işlevinizin şablonlu argüman almasını sağlamaya bir göz atmak isteyebilirsiniz. Şablonlu bir arayüz kullanmak istenmiyorsa, aşağıdaki gibi bir şey kullanmalısınız std::function<void(int, int)>
: bunlar için uygun şekilde çağrılabilir bir fonksiyon nesnesi oluşturabilirsiniz, örneğin, kullanarak std::bind()
.
Sınıf türü veya uygun için bir şablon bağımsız değişkeni kullanan tür güvenli yaklaşımlar , yanlış türe dönüştürme nedeniyle hata olasılığını ortadan kaldırdıklarından std::function<...>
bir void*
arabirim kullanmaktan daha tercih edilir .
Bir üye işlevi çağırmak için bir işlev işaretçisinin nasıl kullanılacağını açıklığa kavuşturmak için, işte bir örnek:
// the function using the function pointers:
void somefunction(void (*fptr)(void*, int, int), void* context) {
fptr(context, 17, 42);
}
void non_member(void*, int i0, int i1) {
std::cout << "I don't need any context! i0=" << i0 << " i1=" << i1 << "\n";
}
struct foo {
void member(int i0, int i1) {
std::cout << "member function: this=" << this << " i0=" << i0 << " i1=" << i1 << "\n";
}
};
void forwarder(void* context, int i0, int i1) {
static_cast<foo*>(context)->member(i0, i1);
}
int main() {
somefunction(&non_member, 0);
foo object;
somefunction(&forwarder, &object);
}