Moja krótka odpowiedź brzmi: nie.
Zignorowanie komentarzy wskazujących, że funkcja statyczna nie powinna być zadeklarowana w pliku .h (jest to część, którą chcesz ukryć - mimo wszystko jest statyczna), oto kilka rzeczy, o których należy pamiętać.
Wygląda na to, że próbujesz użyć interfejsu, aby oddzielić implementację od użytkowników modułu; szlachetny cel. Może to pozwolić na większą elastyczność, ponieważ implementacja może się zmienić w pliku .cc bez przerywania wywoływania kodu. Zastanów się jednak nad zdefiniowanym interfejsem.
Każdy kod korzystający z tego modułu powinien mieć gwarancję, że będzie mógł pobrać instancję Interface za pośrednictwem Init (chociaż musi to być zawarte w pliku .h). Ta instancja interfejsu wskaże funkcje do użycia. Jedną z takich funkcji jest podpis
int Fun(int);
Co ukryłeś? Oczywiście, możesz zmienić funkcję, do której dzwonią, ale nadal musisz podać funkcję z tym podpisem.
Alternatywnie, można po prostu zdefiniować .h jako:
int Fun(int);
a następnie w.c plik, coś jak:
static int StaticFun(int i)
{
// something
}
int Fun(int i)
{
StaticFun(i);
}
Można wyśmiać wywołać inną funkcję w oparciu o jakiś stan wewnętrzny, którym zarządza, lub plik konfiguracyjny, co chcesz. Dlaczego to jest lepsze? Poza tym, że jest prostsze, jest to połączenie statyczne; kompilator może na przykład wywołać połączenie z StaticFun, a nawet z funkcją StaticFun. Połączenia za pośrednictwem wskaźników funkcyjnych zwykle powodują zauważalny spadek wydajności.
Teraz może istnieć przypadek dla obiektu "Interfejs", takiego jaki zdefiniowałeś. Ale byłbym skłonny zasugerować, że nie ma w twoim przypadku, nie bez modyfikacji.
Załóżmy, że funkcja Init
zmienione na:
Interface* Init(some state info);
Teraz obiekt Interfejs można przejść z powrotem może się zmienić w zależności od stanu lub konfiguracji przeszedł w, co pozwala Twój moduł dynamicznie map funkcje. Zasadniczo, moja opinia jest taka, że jeśli faktycznie wywołujesz funkcję statyczną pod spodem, wtedy pracujesz znacznie ciężej niż potrzeba i zapobiegasz optymalizacji kompilatora.
Na marginesie, jeśli zamierzasz przejść do interfejsu (pracuję teraz nad projektem z czymś podobnym), czy mogę zaproponować modyfikację? Coś jak ...
.h plików: plik
const Interface* Init(some state);
.c:
static int FunTyp1(int);
static int FunTyp2(int);
static const Interface typ1 = { &FunTyp1 };
static const Interface typ2 = { &FunTyp2 };
const Interface* Init(some state)
{
if (some state == type1)
return &typ1;
else if (some state == type2)
return &typ2;
}
Zalety:
- Prawdopodobnie nie chcą spożywania kod, aby zmodyfikować berło? Przynajmniej nie mogę wymyślić dobrego powodu.
- Definiowanie tego statycznie pozwala uniknąć niepotrzebnego przydzielania sterty i wycieku pamięci, gdy konsumenci wielokrotnie żądają obiektów interfejsu i zapominają je zwolnić (lub nie wiedzą, że powinni - kto jest właścicielem tego obiektu?).
- Możesz udostępnić pojedynczą (statyczną) instancję obiektu interfejsu dla całego kodu używanego w procesie, nie martwiąc się, że ktoś to zmieni.
Należy pamiętać, że dzięki kilku instancjom inicjowanym statycznie można zdefiniować inny obiekt "Interfejs" dla każdego mapowania funkcji, które mają być obsługiwane.
Lepiej opublikować jedną [witrynę przeglądu kodu] (http://codereview.stackexchange.com/questions) –
Zapomniałeś 'typedef' dla typu' Interface'. –
Tak, zakładając, że typedef jest ... czy to dobry projekt? – user2706540