Class Templates |
|
Like a function, a class can be created as a template. In fact, the class is more flexible than the function. To create a class template that uses a constant value for the parameter, use the following formula: template <PrimitiveDataType ParameterName> Options class ClassName { } The template and class keywords are required, so are the < and the > operators. Also, the curly brackets that delimit a class must be specified. The Options factor can be an appropriate combination of public, private, ref, and/or value keywords. The class keyword is followed by the name of the class, followed by the delimiting curly brackets of a class.
When creating a class template using our formula, the PrimitiveDataType factor must be one of the integer data types built in the C++ language (short, Byte, char, __wchar_t, etc). It cannot be a floating-point type (float, Single, or double). The data type is followed by a name for the parameter. Outside of the > operator, you can specify such factors as the public, the private, the value, and/or the ref keywords, following the same rules applied to the creation of a class in the previous lessons. Here is an example of a class: template <__wchar_t c> public ref class Description { public: Description(); Description(__wchar_t msg) { } ~Description(); void Show(); }; It's important to remember that, with this class creation, the c parameter is a constant. If you define a method in the body of the class, you can use the template parameter as you see fit. Here is an example: template <__wchar_t c> public ref class Description { public: Description(); Description(__wchar_t msg) { } ~Description(); void Show(); }; If you implement a method outside of the body of the class, precede it with the declaration of template <PrimitiveDataType ParameterName> Then, after typing the name of the class and before the :: operator, enclose the parameter name within the < and > operators. Here is an example: template <__wchar_t c> Description<c>::Description() { } When processing the class, you can involve the template parameter as you want. For example, you can pass it to the (cout class or the) Console::WriteLine() method to display it in the console. You can also involve the parameter in an appropriate operation, such as checking it using a conditional operator. Here is an example: template <__wchar_t c> void Description<c>::Show() { switch(c) { case L'i': case L'I': Console::WriteLine(L"Integer"); break; case L'c': case L'C': Console::WriteLine(L"Character"); break; case L'f': case L'F': case L'd': case L'D': Console::WriteLine(L"Decimal"); break; } } Because the template parameter is treated as a constant, you can formally declare it using the const keyword.
After creating a class template, you can use it by primarily declaring a variable. To declare a variable of a class template in the stack, you can use the following formula: ClassName<ValueType> VariableName; The < operator, the > operator, and the ; are required. Like any declaration, you start with the name of the type, in this case the name of the class. Between the angle brackets, specify the same primitive type you used when creating the class. End the stack declaration by the name of the variable. After this declaration, you can use the variable as you see fit. Here is an example: using namespace System; template <__wchar_t c> public ref class Description { public: Description(); Description(__wchar_t msg) { } ~Description(); void Show(); }; template <__wchar_t c> Description<c>::Description() { } template <__wchar_t c> Description<c>::~Description() { } template <__wchar_t c> void Description<c>::Show() { switch(c) { case L'i': case L'I': Console::WriteLine(L"Integer"); break; case L'c': case L'C': Console::WriteLine(L"Character"); break; case L'f': case L'F': case L'd': case L'D': Console::WriteLine(L"Decimal"); break; } } int main() { // Call the function and pass it an integer value Description<L'i'> iDscr; iDscr.Show(); // Call the function and pass it a character value Description<L'c'> cDscr; cDscr.Show(); // Call the function and pass it a double-precision value Description<L'f'> dDscr; dDscr.Show(); return 0; } You can also declare the class variable on the managed heap. To create a handle for the class, in both sides of the assignment operator, type the name of the class followed by the < operator, the type of value, and the > operator. Remember that, for a handle, you must use the ^ and the gcnew operators. Here are two examples: int main() { // Call the function and pass it an integer value Description<L'i'> iDscr; iDscr.Show(); // Call the function and pass it a character value Description<L'c'> ^ cDscr = gcnew Description<L'c'>; cDscr->Show(); // Call the function and pass it a double-precision value Description<L'f'> ^ dDscr = gcnew Description<L'f'>(L'f'); dDscr->Show(); return 0; }
As done for a function, you can create a template without specifying the type of value it would hold. You can declare a member variable of an unknown type. You can pass an unknown type to the methods of a class. To create such a class template, you can use the following formula: template <class Type> Options class ClassName { } Once again, the template and class keywords are required, so are the < and the > operators. Inside the <>, after the class keyword, enter a name for the template. The Options factor can be an appropriate combination of public, private, ref, and value keywords. After the name of the class, represented in our formula as ClassName, delimit the body of the class with the curly brackets. In the body of the class, you can do whatever you judge necessary. You can declare a member variable as a template type. You can pass an argument as a template type to one or more of the methods. Here is an example of a class: template <class TypeOfValue> public ref class Description { public: Description(); Description(TypeOfValue type); ~Description(); void Show(); String ^ Message; TypeOfValue Value; }; If you define a method in the body of the class, you can use the member variable as you see fit. Here is an example: template <class TypeOfValue> public ref class Description { public: Description(); Description(TypeOfValue type) : Value(type) { } ~Description(); void Show(); String ^ Message; TypeOfValue Value; }; As mentioned earlier, if you want to define a method outside of the body of the class, precede it with the declaration of template <class Type> After typing the name of the class and before the :: operator, enclose the template type within the < and > operators. Here is an example: template <class TypeOfValue> Description<TypeOfValue>::Description() { } In both cases, whether defining the method in the body of the class or outside, use the member variable. Here is an example: template <class TypeOfValue> void Description<TypeOfValue>::Show() { Console::WriteLine(L"{0}: {1}", Message, Value); } You can declare a variable of a class template the same way we saw earlier, in the stack or in the managed heap. Here are examples: using namespace System; template <class TypeOfValue> public ref class Description { public: Description(); Description(TypeOfValue type) : Value(type) { } ~Description(); void Show(); String ^ Message; TypeOfValue Value; }; template <class TypeOfValue> Description<TypeOfValue>::Description() { } template <class TypeOfValue> Description<TypeOfValue>::~Description() { } template <class TypeOfValue> void Description<TypeOfValue>::Show() { Console::WriteLine(L"{0}: {1}", Message, Value); } int main() { // Call the function and pass it an integer value // Declare the variable on the stack heap Description<int> iDscr; iDscr.Value = 246; iDscr.Message = L"Integer"; iDscr.Show(); // Call the function and pass it a character value // Declare the variable on the managed heap Description<__wchar_t> ^ cDscr = gcnew Description<__wchar_t>; cDscr->Value = 'G'; cDscr->Message = L"Character"; cDscr->Show(); // Call the function and pass it a double-precision value // Declare the variable on the managed heap Description<double> ^ dDscr = gcnew Description<double>(355.65); dDscr->Message = L"Decimal"; dDscr->Show(); return 0; }
We have seen that a template could be created using the class keyword. As an alternative, you can use the typename keyword instead of class. Here is an example: using namespace System; template <typename TypeOfValue> public ref class Description { public: Description(); Description(TypeOfValue type) : Value(type) { } ~Description(); void Show(); String ^ Message; TypeOfValue Value; }; template <typename TypeOfValue> Description<TypeOfValue>::Description() { } template <typename TypeOfValue> Description<TypeOfValue>::~Description() { } template <typename TypeOfValue> void Description<TypeOfValue>::Show() { Console::WriteLine(L"{0}: {1}", Message, Value); } int main() { // Call the function and pass it an integer value // Declare the variable on the stack heap Description<int> iDscr; iDscr.Value = 246; iDscr.Message = L"Integer"; iDscr.Show(); // Call the function and pass it a character value // Declare the variable on the managed heap Description<__wchar_t> ^ cDscr = gcnew Description<__wchar_t>; cDscr->Value = 'G'; cDscr->Message = L"Character"; cDscr->Show(); // Call the function and pass it a double-precision value // Declare the variable on the managed heap Description<double> ^ dDscr = gcnew Description<double>(355.65); dDscr->Message = L"Decimal"; dDscr->Show(); return 0; } Based on this, the class keyword used for a template creation can be replaced with typename. |
|
||
Previous | Copyright © 2006-2016, FunctionX, Inc. | Next |
|