2012-01-19 10 views
35

Kiedyś byłem pewien, że nie możesz tego zrobić, ale pewnego dnia bawiłem się z jakimś kodem i wydawało się, że kompiluje i działa. Chcę tylko sprawdzić, czy nie mam szczęścia. Czy klasa szablonu może mieć czystą funkcję wirtualną - co, jak sądzę, oznaczałoby również, że dla destruktora byłyby również prawidłowe metody wirtualne?Czy dozwolone są czyste metody wirtualne w klasie szablonu?

template <typename WordType> class DataSource 
{ 
public: 
    DataSource(); 
    DataSource(DataSource const& other); 
    virtual ~DataSource(); 

    virtual void Put(
     WordType const* const data, 
     unsigned int const wordCount) = 0; 
} 

Próbowałem szuka go w Internecie i wszystko, co udało mi się znaleźć to, że nie można mieć metodę wirtualną (czystej lub w inny sposób) w normalnej klasie, takie jak ten:

class DataSource 
{ 
public: 
    DataSource(); 
    DataSource(DataSource const& other); 
    virtual ~DataSource(); 

    template <typename WordType> 
    virtual void Put(
     WordType const* const data, 
     unsigned int const wordCount) = 0; 
} 

A to ze względu na niemożność zarządzania wirtualnym stołem w celu odniesienia się do wszystkich typów możliwych typów, z którymi ta metoda zostanie wdrożona.

Jednakże, jeśli chodzi o funkcję wirtualnego członka klasy szablonu, wygląda na to, że jest inna, ponieważ cała klasa jest "tworzona" za pośrednictwem parametru szablonu, gdy zmienna klasy szablonu jest podana. W tym momencie wirtualna metoda jest podobna do każdej innej wirtualnej metody klasy ze względu na "znajdowanie i zastępowanie" szablonów.

W każdym razie, powtarzając to pytanie na wypadek, gdyby się zgubił: Czy wirtualne (czyste i/lub normalne) funkcje wirtualne są dozwolone w klasie tempate?

+5

Brzmi jak już zorientowali się odpowiedź na to ... –

+3

Jak powiedziałem, przysięgam sobie, że próbował go wcześniej i miał problemy. Kiedy nagle zadziałało, chciałem się upewnić, że to nie tylko dlatego, że byłem na innym kompilatorze, różnych flagach ostrzeżenia/błędów itp. I że zostało to zdefiniowane - najlepiej - że było w porządku przez standard. – Anthony

+2

Ponadto, na ile jest to warte, nie mogłem znaleźć niczego online, które ostatecznie powiedziałoby tak czy inaczej. Jakie jest lepsze miejsce na umieszczenie tych informacji niż SO? – Anthony

Odpowiedz

44

Szablon klasy może rzeczywiście zawierać wirtualne lub czyste funkcje wirtualne. Zostało to wykorzystane przez Andrei Alexandresu w "Modern C++ Design" do implementacji wzorca gości przy użyciu szablonów i list typów. Możesz zobaczyć kod here in his Loki library, jeśli jesteś zainteresowany.

W przypadku większości standardowych implementacji C++ jest to w porządku, ponieważ po utworzeniu szablonu funkcja wirtualna kończy się jako jedna funkcja. W związku z tym liczba slotów potrzebnych w tabeli vtable może być znana w jednostce tłumaczeniowej, więc można wygenerować tabelę.

Jak już wspomniano, nie można korzystać z funkcji wirtualnego elementu szablonu, ponieważ liczba gniazd vtable nie byłaby znana w jednostce tłumaczeniowej.

Mam nadzieję, że to pomoże!

6

Czy wirtualne (czyste i/lub normalne) funkcje wirtualne są dozwolone w klasie tempate?

Tak. Idealnie legalne.

6

Pomyśl o tym, czym jest klasa szablonu - nie jest to sama klasa, ale szablon, którego kompilator może użyć do tworzenia klas.

W związku z tym nie ma powodu, dla którego nie można uwzględnić funkcji wirtualnej (czystej lub innej) w definicji klasy szablonu, ponieważ sama w sobie nie generuje żadnego kodu, w tym wirtualnej tabeli.

Kiedy faktycznie tworzymy instancję klasy, np. DataSource<int>, wtedy kompilator musi tylko zbudować wirtualną tabelę dla tego jednego wybranego typu, więc nie jest ona inna niż funkcja wirtualna (czysta lub nie) dla nie-szablonowej klasy.

1

Szablon klasy z funkcjami wirtualnymi jest absolutnie w porządku. Ale funkcje szablonu z wirtualnym słowem kluczowym poprzedzonym prefiksem klasy lub szablonu nie są dozwolone.Poniżej by pomóc, że:

//This is perfectly fine. 
template <type T> 
class myClass{ 
    virtual void function() = 0; 
}; 

//This is NOT OK... 
template<type T> 
class myClass{ 
     template <type T> 
     virtual void function() = 0; 
}; 
Powiązane problemy