Analyze C ++ Template (below)

zhaozj2021-02-11  201

The nature of the virtual template member function is not allowed in the template class.

Template specialization

Global specialization

Partial specialization

An example of a specialization

You can use template classes like using a normal class, such as you can inherit, you can create a template that inherited from existing templates and has been initialized. If Vector has made all things for you, you are not satisfied, you want to join the function of sort, you can use the following code to expand it.

//: c03: sorted.h

// Template Specialization

#ifndef sorted_h

#define sorted_h

#include

Template

Class Sorted: PUBLIC std :: Vector

{

PUBLIC:

Void sort ();

}

Template

Void sorted :: sort ()

{

// a bubble sort

For (int i = size (); i> 0; I -)

For (int J = 1; j

IF (at (j-1)> AT (j))

{

// swap the two Elements:

T t = at (j-1);

AT (j-1) = at (j);

AT (j) = t;

}

}

// Partial Specialization for Pointers:

Template

Class sorted : public std :: vector

{

PUBLIC:

Void sort ();

}

Template

Void sorted :: sort ()

{

For (int i = size (); i> 0; I -)

For (int J = 1; j

IF (* at (j-1)> * at (j))

{

// swap the two Elements:

T * t = at (j-1);

AT (j-1) = at (j);

AT (j) = t;

}

}

// Full Specialization for char *:

Template <>

Void sorted :: sort ()

{

For (int i = size (); i> 0; I -)

For (int J = 1; j

IF (strCMP (at (j-1), at (j))> 0)

{

// swap the two Elements:

CHAR * T = AT (j-1);

AT (j-1) = at (j);

AT (j) = t;

}

}

#ENDIF // sorted_h ///: ~

This sorted template enforces a restriction on all uses it: they must contain a ">" operator, in SSTRING, this feature has been explicitly added, but in the Integer class, the automatic type converter Int provides one "Built-in" operation. When a template is willing to provide more functions, the deal's cost is often more requests for your class, so please note that the cost of the operator here, the Integer class may have to be special code to implement these functions.

The default sort template can only work with objects (including objects for constructive). However, it does not sort the pointer to the object, so local specialization is necessary. Even localized code cannot be sorted to the array of char * type, which is we have to need a global special comparison char * element, using strcmp () to do appropriate operations. Here is an example in use the random number of random numbers we speak.

//: c03: sorted.cpp

// Testing Template Specialization

#include "sorted.h"

#include "urand.h"

#include "../Arraysize.h"

#include

#include

Using namespace std;

Char * words [] = {

"IS", "running", "BIG", "DOG", "A",

}

Char * Words2 [] = {

"THIS", "That", "THETHER",

}

int main ()

{

Sorted IS;

URAND <47> Rand;

For (int i = 0; i <15; i )

IS.PUSH_BACK (Rand ());

For (int L = 0; l

Cout << IS [l] << '';

Cout << Endl;

Is.sort ();

For (int L = 0; l

Cout << IS [l] << '';

Cout << Endl;

// Uses the Template Partial Specialization:

Sorted ss;

For (int i = 0; i

SS.PUSH_BACK (New String (Words [i]));

For (int i = 0; i

Cout << * ss [i] << '';

Cout << Endl;

s.sort ();

For (int i = 0; i

Cout << * ss [i] << '';

Cout << Endl;

// Uses the full char * Specialization:

Sorted scp;

For (int i = 0; i

SCP.PUSH_BACK (Words2 [i]);

For (int i = 0; i

COUT << SCP [i] << '';

Cout << Endl;

SCP.SORT ();

For (int i = 0; i

COUT << SCP [i] << '';

Cout << Endl;

} ///: ~

Each template instance here uses different versions of the template. Sorted Using "Ordinary", a template that is not specified, sorted uses global specialization. Prompt you: If there is no global specialization, you may be stupid to think about such a problem: the program seems to work very normal, because the Words array is neatly sorted; "A Big Dog is running", but the same It is the use of local specialization. Words2 cannot work properly. For the result of our desire to pursue, the global specialization is necessary.

Specialization

Template function partial order

Design and efficiency

In sorted, each time you call Add (), the element is inserted into an array, then the array is sorted. Here, the scary inefficient and criticized bubble sorting algorithm is used. But this is totally agreeable because it is a private implementation. In the process of program development, your priority is:

1. Get the correct class interface.

2. Of course, as accurate as possible, it is also as fast as possible.

3. Verify your design

Typically, you can only find out the problems in the class in the class when you organize your most primary "first draft". You may also find some kinds of classes that can be used as a good helper when assembling and checking your original implementation code, such as containers, Iterators, etc. Sometimes, it is difficult to find such a problem during the analysis process. During the analysis, your goal is just a magnificent blueprint and fast implementation and testing. Only after the design phase, you can realize that you should take some time to re-consider it and carefully consider the topic above.

Prevent template expansion

Every time you instantiate a template, the code of the template will be regenerated (except in the INLINE tag function), if a template does not depend on a particular type of parameters, then they can place a general base class. In order to prevent meaningless code rebirth. For example, in the previous chapter, INHERITSTACK.CPP regulations, only the stack type can accept the process call, the following is the templated code version.

//: c03: nobloat.h

// Templatized inheritstack.cpp

#ifndef nobloat_h

#define nobloat_h

#include "../c0a/stack4.h"

Template

Class NBSTACK: PUBLIC STACK

{

PUBLIC:

Void Push (T * STR)

{

Stack :: Push (STR);

}

T * peek () const

{

Return (T *) stack :: peek ();

}

T * POP ()

{

Return (T *) stack :: pop ();

}

~ Nbstack ();

}

// Defaults to Heap Objects & Ownership:

Template

NBSTACK :: ~ nbstack ()

{

T * TOP = POP ();

While (TOP)

{

DELETE TOP;

TOP = POP ();

}

}

#ENDIF // Nobloat_H ///: ~

I want to mention the previously mentioned that the inline function does not generate new code, which is free. During the whole process, the functional code is only once when we create the base class code, and the issue of rights is also increased The new destructor (the type is independent, created by template). Note the following code, when the destructor of the base class is called, the stack is cleared, so there will be no problem with repeated release. //: c03: Nobloattest.cpp

#include "nobloat.h"

#include "../require.h"

#include

#include

#include

Using namespace std;

Int main (int Argc, char * argv [])

{

Requireargs (Argc, 1); // File Name is Argument

IFStream in (Argv [1]);

Assure (in, argv [1]);

NBSTACK TextLines;

String line;

// read file and store lines in the stack:

While (In, Line))

TextLines.push (New String (line));

// Pop The Lines from the stack and print them:

String * S;

While ((s = (string *) textlines.pop ())! = 0)

{

COUT << * s << endl;

Delete S;

}

} ///: ~

External instantiation

Sometimes, an external instantiation a template is very useful. That is to say: The compiler will put down the code to wait for a special version of the template. Even if you haven't intended to create an object, in order to do this, you can use the template key by following the following method.

Template Class Bobbin ;

Template void sort (char * []);

Below is an example of sorted.cpp, which has been instantified a template before use.

//: c03: explicitinstantiation.cpp

#include "urand.h"

#include "sorted.h"

#include

Using namespace std;

// Explicit Instantiation:

Template Class Sorted ;

int main ()

{

Sorted IS;

URAND <47> rand1;

For (int K = 0; k <15; k )

IS.PUSH_BACK (RAND1 ());

Is.sort ();

For (int L = 0; l

COUT << IS [L] << ENDL;

} ///: ~

In this example, the external instantiation does not really do, without them, the program will run as usual, and the external instantiation only explains the need to external control.

External instantiation template function

Control template instantiation

Usually the template is only instantiated when needed, and the function template, this means you call it at the moment, but to the type of model, it is more refined, only in the template When a function, the function will be instantiated, in other words: Only the member function we use is instantiated, for example: //: c03: delayedInstantiation.cpp

// MEMBER FUNCTIONS of Class Templates Are Not

// instantiated until the're needed.

Class X

{

PUBLIC:

Void f () {}

}

Class Y

{

PUBLIC:

Void g () {}

}

Template Class Z

{

T t;

PUBLIC:

Void a () {t.f ();

Void b () {t.g ();

}

int main ()

{

Z zx;

Zx.a (); // doesn't create z :: b ()

Z Zy;

Zy.b (); // doesn't create z :: A ()

} ///: ~

Here, even in the template, it intends to use the two member functions F () and g (), but the fact is: the program's compilation process describes that it is only in Z :: (), Talented external instantiation ZX, and we can also explain Z .

Contains VS separation mode

Keyword export

Template programming habits

Deep research - induction

Summary: When you try to use the template to write your own code, you will find a major defect in C , especially the STL code, you will get compiling error messages, for the compiler, it can't resist the spray Countless people who are not predicting, after a small party, you can adapt the code (although this looks a little wild), it is worth a comfort, it is: C compiler gets some benefits from it, before, they just can The code you instantiate the template is wrong, but now they can make the root knot that triggers this error in your template definition.

Here is the topic of the template implied interface. Even if the keyword templa declares: "I support all types", the code in the template definition must also have support for certain targeted operations and member functions, that is, the interface. So in reality, a template definition can be said: "I support various types However, this interface is included." If you just want the compiler to say that the template you try to instantiate the template, "Sorry, you want to instantiate What I don't support in the template is simpler. The Java language has a characteristic of the interface, which is very perfect for this, (but Java has no parameter type mechanism), if one day you can see C , it will be a long time. Things, the compiler can only report to the instantiation template error, then you can only grind your teeth, find the first line of error, and start modifying it.

Written in the last: I translated this article is very simple, I don't understand it, I have never seen such a difficult thing since I have learned myself. But I never doubt my understanding, now this translation completely represents my thoughts, can say that I am completely translated according to my own thought process, how do I think about how to turn, I want the author's purpose But so. If this translation can help more people understand and learn C

Template, it will be my happiest and happy, but I declare in advance, I don't want to see someone to make money!

转载请注明原文地址:https://www.9cbs.com/read-4356.html

New Post(0)