Zasadnicza koncepcja do zrozumienia jest to, że wystąpienie szablon jest po prostu klasa. Zasadniczo nie różni się od innych klas.
Kiedy masz typową definicję szablonu:
template<typename T> class Base;
Następnie instancji szablonu:
Base<int>
jest tylko klasa o tej nazwie. Nie ma to nic wspólnego z int
i nie ma absolutnie żadnego związku, z int
. Nie odziedziczy go w żaden sposób ani w żaden sposób.
Następny krok:
class Derived;
template<typename T> class Base {};
Base<Derived> foo;
Znowu Base<Derived>
jest po prostu klasa. Nie ma żadnego wewnętrznego związku z Derived
. Nie pochodzi z niego, nie dziedziczy po nim, nic.
Więc teraz bierzemy końcowy etap:
template<class T>
class Base
{
};
class Derived : public Base<Derived>
{
};
Ten deklaruje klasę o nazwie Derived
, która dziedziczy z klasy o nazwie Base<Derived>
. A Base<Derived>
to tylko klasa. To bardzo prosta klasa. Nie można zrobić nic prostszego. Nie ma żadnych metod. Nie ma żadnych członków. Ani prywatne, chronione ani publiczne. Jest to malutka klasa, ale ma te same prawa i przywileje, co każda inna klasa. Możesz zadeklarować do niego wskaźnik. Lub odniesienie do niego. To tylko klasa.
Znowu kluczową koncepcją jest to, że instancja szablonu jest po prostu klasą. Nie "dziedziczy" w żaden sposób z klasy, która jest parametrem szablonu. W tym przypadku instancja szablonu jest całkowicie pusta, ale może zrobić wszystko, co może zrobić każda inna klasa. Może mieć członków publicznych, prywatnych i chronionych. Może pochodzić z innej klasy, która może być inną instancją szablonu (ponieważ instancja szablonu jest tylko klasą). Inna klasa może pochodzić z instancji szablonu, ponieważ instancja szablonu jest po prostu klasą.
Nie ma tu nieskończonego gniazdowania. Po prostu masz jedną klasę dziedziczącą z innej klasy. Druga klasa to instancja szablonu, ale czy zdarzyło mi się wspomnieć, że instancja szablonu to tylko klasa?
W kontekście 'Base',' T' nie jest w pełni kompletnym typem. Z tego powodu nie można uzyskać dostępu do rzeczy takich jak 'typedef's zdefiniowane w' T' z 'Base' (patrz [1] (http://stackoverflow.com/questions/6006614/c-static-polymorphism-crtp- i-using-typedefs-from-derived-classes) i [2] (http://stackoverflow.com/questions/652155/invalid-use-of-incomplete-type)). Ponieważ 'T' nie jest w pełni kompletnym typem, kompilator nie musi w nieskończoność rekurencyjnie występować w tej sytuacji. Przynajmniej to moje zrozumienie. – Cornstalks
@ Eichhörnchen Ponieważ wywodzę się z Base, która jest szablonowana przez Derived, która dziedziczy po Base, która jest szablonowana przez Derived, która dziedziczy po Base ... –
@Cornstalks yea sounds about right –