5

Chcę zapisać wskaźnik na obiekcie i wskaźnik do jego metody znanego podpisu. Jeśli znam klasę, to wskaźnik ma typ:C++ przechowuj wskaźnik do funkcji składowej nieznanej klasy

int (MyClass::*pt2Member)(float, char, char) 

Ale jak mogę przechowywać wskaźnik, jeśli nie znam typu?

chcę zrobić coś takiego:

myObject.callThisFuncLater(&otherObject, &otherObject::method) 

Jak mogę przechowywać wskaźnik do metody method w myObject i nazywają to później?

+1

Sześć miliardów duplikatów. – Puppy

+1

@DeadMG: pokaż im :) mój licznik utknął przy 2 178 933 wszystkich pytaniach – sehe

+0

Jakich argumentów użyjesz, gdy zadzwonisz później? – Beta

Odpowiedz

2

Możesz użyć boost::function (i boost::bind), aby zapisać kod, który będzie później wywoływany.

class MyClass 
{ 
public: 
    void callThisFuncLater(boost::function< int (float, char, char) > callBack); 
}; 
... 
myObject.callThisFuncLater(boost::bind(&otherObject::method, &otherObject)); 
+1

Mogę się mylić, ale czy należy włączyć '& otherObject' i' & otherObject :: method'? – Vortico

+0

@Vortico Masz rację, przepraszam. Zamierzam edytować mój wpis, aby go poprawić. –

5

Najłatwiej to zrobić, jeśli masz dostęp do rozszerzeń biblioteki STL (TR1 dostępnych na GCC i Visual Studio 2008 roku i jest. Std :: Funkcja i std :: wiążą mogą być wykorzystane do otoczyć . inwokacja, który może być nazywany później funkcjonalność dostępna w funkcji pobudzenia i zwiększenia wiążą się również:.

#include <functional> 

class MyClass { 
public: 
    template<typename T> callThisFuncLater(T& otherObject, 
             int(T::*)(float, char, char) method) { 
    return storedInvocation_ = std::bind(otherObject, 
            method, 
            std::placeholders::_1, // float 
            std::placeholders::_2, // char 
            std::placeholders::_3); // char 
    } 

    int callStoredInvocation(float a, char b, char c) { 
    storedInvocation_(a, b, c); 
    } 

private: 
    std::function<int(float, char, char)> storedInvocation_; 
}; 
-1

Osobiście wybrałbym inną konstrukcję prostu dlatego wskaźniki funkcji członka w C++ nie są łatwe do pracy z Osobiście. zdecydowałby się używać interfejsów i dziedziczy po nich i analizuje je wzdłuż:

Jednym z problemów z wskaźnikami funkcji członów jest to, że są one implementowane w różny sposób na różnych kompilatorach. Jeśli korzystasz z kompilatorów Borland/Embarcardero i chcesz ograniczyć się do tego, możesz użyć słowa kluczowego __closure, ale najprawdopodobniej nie jesteś, a zatem musisz użyć innej implementacji określonej dla kompilatora lub użyć jednego z boosterów takie funkcje pomocnicze.

Ale jeśli znajdujesz się w sytuacji, w której pomocne jest korzystanie z wskaźników funkcji członków w C++, przemyśl swój projekt.

+0

Standardową alternatywą dla zamknięć są funkcje lambda, ale to wciąż nie jest realistyczny zamiennik funkcji składowych. – MSalters

3

Nie ma sposobu, aby to zrobić, jak pierwotnie wbudowano w bibliotekę językową lub standardową (chociaż ostatnio została dodana). Jeśli znasz Boost, zawierają rozwiązanie tego - Boost.Function.

Jeśli z jakiegoś powodu jednak nie jesteś w stanie lub nie chcą używać Boost jest rodzajowy sposób to zrobić przy użyciu szablonów (które, co prawda, jest dość podobna do Boost na rozwiązanie):

class FncPtr 
{ 
public: 
    virtual int call(float, char, char) = 0; 
}; 

template <typename T> 
class ClassFncPtr : public FncPtr 
{ 
    int (T::*pt2Member)(float, char, char); 
    T *inst; 
public: 
    ClassFncPtr(T* who, int (T::*memfunc)(float,char,char)) 
     : inst(who), pt2Member(memfunc) 
    { 
    } 
    int call(float a, char b, char c) 
    { 
     return (inst->*pt2Member)(a,b,c); 
    } 
}; 

template <typename T> 
FncPtr * makeFuncPointer(T* who, int (T::*memfunc)(float,char,char)) 
{ 
    return new ClassFncPtr<T>(who,memfunc); 
} 

Możesz również podklasę FncPtr, aby móc korzystać z funkcji nieklasowanych, jeśli chcesz.

Powiązane problemy