function Templates provides a mechanism through which we can preserve the semantics of function definitions and function calls encapsulate a piece of code at a program location to ensure that the arguments are evaluated only once before the function call .
A function template provides an algorithm that is used to automatically generate instances of various types of functions for all or part of the function interface parameters and return types. parameterization (parameterize) The body of the function remains unchanged .
Usage Considerations for Function templates:
1. You need to add a template declaration in front of each function template For example:template<typename t>
2. When using the template class, pay attention to its type change, for example:
Template<typename T>class seqlist{}; The template class is of type Seqlist<t> and Seqlist is only a class name
3. Function templates cannot be compiled separately in. h files and. cpp files
When implementing a sequential table, we need it to store any type of data. However, special consideration is given to string type objects. Let's analyze the common copy method.
1) copy-by-object
Pros: No special considerations for the type of data
Cons: Copy is less efficient
2) memcpy () copy
Advantage: High efficiency of copy
Disadvantage: When copying a pointer, multiple pointers may appear to point to the same space, causing the memory release to cause the program to crash multiple times.
Deep anatomy of the String class
In different compilers, the size of the string class is different, but it can be determined that there is a 16-byte buffer space in the string class for storing short-length characters Fraiti high efficiency, and a 4-byte--ptr used to point to a string space that is longer than 15 o'clock characters. There are also two 4-byte _size and _capacity used to represent size and capacity. A total of 28 bytes.
650) this.width=650; "src=" Http://s5.51cto.com/wyfs02/M00/7D/F7/wKioL1b0AILCwoBaAAA0WGdy8ks871.png "title=" Qq20160324225500.png "alt=" Wkiol1b0ailcwobaaaa0wgdy8ks871.png "/>
Here it is necessary to consider the replication at the time of expansion and copy construction, if the length of the string is greater than 15, then using memcpy () is only a copy of the numeric value, and does not request space for _ptr causes multiple pointers to point to the same space, so that the space is released multiple times to cause the program to crash.
#include <iostream> #include <string>using namespace std;const int size = 3;//The default size of the constructed object const int deafault = 3;//the size of each expansion template<typename t> class seqlist{public://constructor Seqlist ();//Copy constructor seqlist (const seqlist& l);//Assignment seqlist<t> operator= (seqlist l);//destructor ~seqlist ();p ublic:void pushback (const t& d); void popback (); Void pushfront (const t& d); Void popfront (); void sortlist (); void reverse (); T* find (const t& d); Void insert (int pos, const t& x); void remove (t x); Void removeall (t x); void checkcapacity (); Void print ();p rivate:t* _data;int _size;int _capacity;}; Template<typename t>void seqlist<t>::P rint () {int i = 0;for (i = 0; i < _size; i++) {Cout << _data[i] << " ";} Cout << endl;} template<typename t>//Constructor Seqlist<t>::seqlist (): _data (New t[size]), _size (0), _capacity (SIZE) {}template<typename t>//copy constructor seqlist<t>::seqlist (const seqlist& l) {_data = new t[l._size];int i = 0;for (i = 0; i < l._size; i++)//copy {_data[i] = l._data[i];} _size = l._size;_capacity = _size;} template<typename t>//Assignment seqlist<t> seqlist<t>:: operator= (SeqList l) { Swap (_data, l._data); _size = l._size;_capacity = l._capacity;return *this;} template<typename t>//destructor seqlist<t>::~seqlist () {if (_data != null) {delete[] _data;_data = null;}} Template<typename t>void seqlist<t>::checkcapacity ()//Detection capacity {if (_size == _ capacity)//capacity expansion {T* tmp = new t[_capacity + deafault];//memcpy (tmp, _data, sizeof (T) *_size); Shallow copy, resulting in program crashes int i = 0;for (i = 0; i < _size; i++)//copy {tmp [I] = _data[i];} Delete[] _data;_data = tmp;_capacity += deafault;}} Template<typename t>void seqlist<t>::P ushback (const t& d) {CheckCapacity (); _data[_size] = d;_size++;} Template<typename t>void seqlist<t>::P opback () {if (_size == 0) {return;} _size--;} Template<typename t>void seqlist<t>::P Ushfront (const t& d) {CheckCapacity () ;int i = 0;for (i = _size-1; i >= 0; i--) {_data[i + 1] = _data[i];} _data[0] = d;_size++;} Template<typename t>void seqlist<t>::P Opfront () {if (_size == 0) {return;} int i = 0;for (i = 1; i < _size; i++) {_data[i - 1] = _data[i];} _size--;} Template<typename t>void seqlist<t>::sortlist () {int i = _size;bool The flag = true;//flag bit, when the order table is already ordered, does not need to be reordered to improve efficiency for (i = 1; i < _size && flag; i++) {int j = 0;flag = false;for (j = 0; j < _size - i; j++) {if (_data[j] > _data[j + 1 ]) {Flag = true;swap (_data[j], _data[j + 1]);}}} Template<typename t>void seqlist<t>::reverse () {int left = 0;int right = _size;while (left < right) {swap (_data[left++], _data[right++]);}} Template<typename t>t* seqlist<t>::find (const t& d) {int i = 0;for (i = 0; i < _size; i++) {if (_data[i] == d) {return &_data[i];//Find return address}}return null;// No}template<typename t>void seqlist<t>::insert found (int pos, const t& x) {if (pos > 0 && pos <= _size)//Determine the correctness of the position {CheckCapacity ();int i = 0;for (i = _size - 1; i >pos-2; i--) {_ Data[i + 1] = _data[i];} _data[pos - 1] = x;_size++;}} Template<typename t>void seqlist<t>::remove (t x) {int i = 0;for (i = 0; i < _size; i++) {if (X == _data[i]) {for (int j = i; j < _size-1; j++ ) {_data[j] = _data[j + 1];} _size--;return;}}} Template<typename t>void seqlist<t>::removeall (t x) {int i = 0;for (i = 0; (i < _size; i++) {if (X == _data[i]) {Remove (x), i--;//keep subscript, delete, and then continue looking from the current, Prevent the sequential table traversal from leaking out. }}}void test1 () {seqlist<string> l;//l.pushback (1);//l.pushback (2);//l.pushback (3);//l.PushBack (4);//l.print ();//l.popback ();//l.print ();//l.popback ();//l.print ();//l.popback ();//l.print (); L.pushfront (" 11111 "); L.pushfront (" 22222 ");//l.pushfront (" 333333333333333333333333333333333333 "); L.pushfront (" 33333 "); l.pushfront ("44444");//l.pushfront ("11111"); L.print (); cout << sizeof (String) << endl;//cout << l.find ("11111") << endl;////cout < < l.find (0) << endl;//l.insert (4, "00000");//l.print ();//l.removeall ("11111");//l . Print ();//l.sortlist ();////l.popback ();//l.print ();//l.popback ();//l.print ();//l.popback ();//l.print ();} Int main () {test1 (); GetChar (); return 0;}
When using memcpy ()
Test code
L.pushfront ("11111"), L.pushfront ("22222"),//l.pushfront ("333333333333333333333333333333333333"); L.PushFront (" 33333 "); L.pushfront ("44444");
The results can be run correctly
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M00/7D/F7/wKioL1b0BN3TVzvyAAAa2BvvFO8349.png "title=" Qq20160324230413.png "alt=" Wkiol1b0bn3tvzvyaaaa2bvvfo8349.png "/>
But when the string length is longer
L.pushfront ("11111"), L.pushfront ("22222"), L.pushfront ("333333333333333333333333333333333333");//l.PushFront (" 33333 "); L.pushfront ("44444");
650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M01/7D/FA/wKiom1b0BICBLXsmAAAfjWbrsnU907.png "title=" Qq20160324230509.png "alt=" Wkiom1b0bicblxsmaaafjwbrsnu907.png "/>
Program crashes
Functions of function templates in C + + dynamic sequential table