C ++ basic knowledge Review (string basics, smart pointers, iterators, and containers)

Source: Internet
Author: User

C ++ basic knowledge Review (string basics, smart pointers, iterators, and containers)
[2, 1.1] string Construction

1 # include <iostream> 2 # include <string> 3 4 int main () 5 {6 using namespace std; 7 8 cout <"1 --- string (const char * s): Initialize the string object to the C-style string pointed to by s "<endl; 9 string one (" benxintuzi_1 "); 10 cout <"one =" <one <endl; // overload <11 12 cout <"2 --- string (size_type n, char c ): initialize A string object containing n characters in character c "<endl; 13 string two (20, '$ '); 14 cout <"two =" <two <endl; 15 16 cout <"3 --- string (const string & str): copy constructor initialization" <endl; 17 string three (one); 18 cout <"three =" <three <endl; 19 20 cout <"4 --- string (): default constructor "<endl; 21 string four; 22 four + = one; // overloaded + = 23 four = two + three; // overload + 24 cout <"four =" <four <endl; 25 26 cout <"5 --- string (const char * s, size_type n ): use the first n characters of the C-style string pointed to by s to initialize the string object "<endl; 27 char s [] =" benxintuzi "; 28 string five (s, 5 ); 29 cout <"five =" <five <endl; 30 31 cout <"6 --- string (Iter begin, Iter end): use [begin, end) initialize the string object "<endl; 32 string six (s + 2, s + 5); 33 cout <" six = "<six <endl; 34 35 cout <"7 --- string (const string & str, string size_type pos = 0, size_type n = npos ): initialize the string object to the n characters starting from pos in str "<endl; 36 string seven (four, 5, 2 ); 37 cout <"seven =" <seven <endl; 38 39/* 40 cout <"8 --- string (string & str) Nout t: initialize the string object to str, and possibly modify str. Move the constructor [C ++ 11 new features] "<endl; 41 42 cout <"9 --- string (initializer_list <char> il: Initialize the string object to the character [C ++ 11 new features] in the initialization list il" <endl; 43 string nine = {'T', 'U', 'z', 'I'}; // or string nine {'T', 'U', 'z ', 'I'}; 44 cout <"nine =" <nine <endl; 45 */46}

 

[1.2] string input for C-style strings, there are three input methods: char info [100]; cin> info; // read a word from the stream and store it in info. cin. getline (info, 100); // read a row from the stream and store it in info. Delete \ n cin in the stream. get (info, 100); // read a row from the stream and store it in info. Keep \ n in the stream. For string objects, there are two input methods: string stuff; cin> stuff; // read the word getline (cin, stuff) from the stream; // read a row from the stream. Delete the \ n getline in the stream to specify the Separator Used to separate words, put it in the third parameter, such as: cin. getline (info, 100, ':'); // This form is used for C-style strings. getline (stuff, ':'); // This is used by the string class. Comparison between string and traditional C-style strings: when using string-type input, you do not need to specify the number of characters entered. The string size can be automatically matched and must be specified when using a C-style string, because the C-style string uses the istream class method, while the string version uses an independent function, there are differences in form. This difference is also reflected in other operators, for example,> OPERATOR: C-style string: cin. operator> (fname), and string type: operator (cin, fname); Note: getline () of the string version ends reading in the following three cases: 1 ends at the end of the file: in this case, the eofbit is set in the input stream. 2. The default Delimiter is \ n. In this case, the \ n in the stream is deleted. 3. The maximum number of characters read is [min (string: npos, idle memory)]. At this time, the failbit of the input stream is set. There is a statistical system in the input stream for tracking the status of the stream: 1 to detect the end of the file, set the eofbit register; 2 to detect errors, set the failbit register; 3 to detect unrecognized faults, set the badbit register. 4. Set the goodbit register when everything goes well. The string class reloads all six Relational operators. For each relational operator, three additional reloads are performed: string object and string object, and string object C-style string; c-style string and string object. [2] smart pointers are similar to pointers, but they are classes. It can help manage dynamically allocated memory. There are three options: auto_ptr \ unique_ptr \ shared_ptr. Auto_ptr is provided by C ++ 98, and C ++ 11 has been abandoned (although it has been abandoned, it is still widely used ). TIPS: Why should the new standard abandon auto_ptr? The reason is as follows: assume that the values are: auto_ptr <string> ps1 (new string ("benxintuzi"); auto_ptr <string> ps2; ps2 = ps1; If ps2 and ps1 are normal pointers, then they will point to a heap memory at the same time. If the auto_ptr Pointer Points to a heap memory at the same time, it will call two delete operations. This is terrible. Therefore, auto_ptr adopts the policy that if a value is assigned, ps1 will be set to 0. Similarly, unique_ptr adopts this policy, but it is stricter. As follows: When ps2 = ps1, that is, ps1 is null, if * ps1 is called, it is equivalent to calling an object pointed by a null pointer. In auto_ptr, it can be compiled and passed, an error occurs during running. However, in the case of unique_ptr, you will not be allowed to compile it. The conclusion is that unique_ptr is safer than auto_ptr. Shared_ptr maintains a reference count pointing to the same object for each heap object. delete is called only when the reference count is 0. Therefore, shared_ptr supports smart pointer assignment. To create a smart pointer, you must include the header file memory and then use the template syntax to instantiate the required type of pointer. For example, auto_ptr contains the following constructor: template <class X> class auto_ptr {public: // throw () means no exception is thrown. [C ++ 11 also discards throw ()] explicit auto_ptr (X * p = 0) throw ();...} therefore, the use of smart pointers is very simple. You only need to initialize them with specific types of pointers, such as auto_ptr <double> pd (new double). Note: smart pointers are placed in the namespace std (note that both shared_ptr and unique_ptr are newly added in C ++ 11, which may not be supported by the old compiler ).
 1 #include <iostream> 2 #include <string> 3 #include <memory> 4  5 class Report 6 { 7 public: 8     Report(const std::string s) : str(s) 9     {10         std::cout << "Object created!" << std::endl;11     }12     ~Report()13     {14         std::cout << "Object deleted!" << std::endl;15     }16     void comment() const17     {18         std::cout << "str = " << str << std::endl;19     }20 21 private:22     std::string str;23 };24 25 int main()26 {27     std::auto_ptr<Report> pa(new Report("using auto_ptr"));28     pa->comment();29 30     std::shared_ptr<Report> ps(new Report("using shared_ptr"));31     ps->comment();32 33     std::unique_ptr<Report> pu(new Report("using unique_ptr"));34     pu->comment();35 36     return 0;37 }38 39 /** output */40 Object created!41 str = using auto_ptr42 Object created!43 str = using shared_ptr44 Object created!45 str = using unique_ptr46 Object deleted!47 Object deleted!48 Object deleted!

 

Note: Do not assign a non-heap memory pointer to a smart pointer. Otherwise, although compilation can be performed, the situation is not always optimistic. This is equivalent to deleting non-heap memory, it is easy to cause hard-to-find problems. We recommend that you use shared_ptr if you need multiple valid pointers pointing to the same heap object. This includes: 1. There is a pointer array and some auxiliary pointers are used to identify special elements, such as the most value element; 2. Both objects contain pointers pointing to the third object; 3. pointers in STL containers. Many STL algorithms support copying and assigning values. If the program does not need multiple valid pointers pointing to the same heap object at the same time, use unique_ptr. If you want to use unique_ptr as the right value, you can assign it to shared_ptr. When the unique_ptr condition is met, you can also use auto_ptr, however, unique_ptr seems to be a better choice (if the compiler does not provide unique_ptr, you can use scoped_ptr provided by the boost library, which is similar to unique_ptr ). [3] iterator [3.1] iterator basic iterator is a broad pointer that can be incrementally operated and referenced. Each container class defines an iterator related to it. The iterator is a typedef definition named iterator and its scope is the entire class. Templates make the algorithm independent from the data type, while the iterator makes the algorithm independent from the container type. The iterator is mainly used to traverse elements in the container. It should have the following basic functions: 1. Support the unreference operation; 2. assign a value; 3. Compare operations, such as = ,! = 4 the auto-increment operation has the above capabilities. In fact, STL defines a variety of (5) iterators according to the functions of the iterator. The description is as follows: The iterator type indicates that the input iterator [read container] can read elements in the container, however, elements in the container may not be modified. The input iterator must be able to access all elements in the container. Therefore, it supports ++ operations. The output iterator write container program can modify the element values in the container, but cannot read the elements in the container. Forward iterator [read or write container] One-Way read/write. Two-way iterator [two-way read or write container] Two-way read/write. Supports the auto-subtraction operator. The Random Access iterator [two-way read or write container] provides additional "Skip" access capabilities. Meanings of operations supported by the iterator: the expression indicates that a + n and n + a point to the nth element after the nth element a-n points to the nth element r + = n, r-= n r = r + n, r = r-n a [n] * (a + n) b-~ Number of elements in range B a <B, a> B, a> = B, a <= B logical judgment STL iterator function Summary: summary: generally, the iterator supports read or write operations for unreference. All types of iterators Support auto-increment operations. The auto-subtraction operation is only supported by the bidirectional iterator and the random access iterator; the Random Access iterator provides the possibility of "Skip" access. Therefore, the iterator capacity can be expressed as follows: random Access iterator> bidirectional iterator> forward iterator> input iterator = output iterator [3.2] iterator advanced iterator is a generalized pointer, pointers meet the requirements of all iterators. Therefore, STL algorithms can use pointers to operate non-STL containers based on pointers. For example, you can use the STL Algorithm for Arrays: To sort a double Receipts [100], you can use the STL algorithm sort, but the input is indeed a pointer, such as: sort (Receipts, receipts + 100); STL provides some predefined iterators: copy (), ostream_iterator, and istream_iterator. Suppose it is defined as follows: int casts [10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; vector <int> dice (10); copy (casts, casts + 10, dice. begin (); // copy data in the range [casts, casts + 10) to dice. output stream iterator in the target space starting with begin (): If you need to copy the data to the display, you need an iterator that represents the output stream. STL provides the ostream_iterator template for us. This iterator is an adapter that converts all interfaces to the interfaces used by STL. We must include the header file iterator and make the following declaration to create the iterator: # include <iterator>... ostream_iterator <int, char> out_iter (cout, ""); Description: int: indicates the Data Type sent to the output stream; char: indicates the character type used by the output stream; In the constructor, cout: indicates the output stream to be used; "": indicates the separator of the sent data. You can use the iterator: * out_iter ++ = 15; // equivalent to cout <15 <"; this statement indicates that" 15 "is assigned to the position pointed by the pointer, and then the pointer moves forward to a unit. Copy (dice. begin (), dice. end (), out_iter) to copy the entire dice container range to the display. You can also create an anonymous iterator as follows: copy (dice. begin (), dice. end (), ostream_iterator <int, char> (cout, ""); input stream iterator: for input stream iterators, istream_iter template: copy (istream_iterator <int, char> (cin), istream_iterator <int, char> (), ostream_iterator <int, char> (cout, ""); Description: int: data type to be read; char: the data type used by the input stream. In the constructor, the first parameter cin indicates that the input stream managed by cin is read. If the constructor is omitted, the input fails, therefore, the above Code reads int type data from the input stream and outputs the data to the screen until the end of the file, the type does not match, or other input faults occur.
 1 #include <iostream> 2 #include <iterator> 3 using namespace std; 4  5 int main() 6 { 7     copy(istream_iterator<int, char>(cin), istream_iterator<int, char>(),  8          ostream_iterator<int, char>(cout, " ")); 9     return 0;10 }11 12 /** output */13 1 2 3 4 514 1 2 3 4 5 __  

 

In addition to istream_iterator and ostream_iterator, the header file iterator also provides some dedicated iterators, such as reverse_iterator, back_insert_iterator, front_insert_iterator, and insert_iterator. When the reverse_iterator increments, the pointer actually decreases. For example, rbegin () and rend () in the vector class return the pointer pointing to the next position of the last element and the pointer pointing to the first element respectively. Note: although the pointers returned by rbegin () and end () point to the same position, their types are different. The former type is reverse_iterator, and the latter type is iterator. It is also worth noting that the specific implementation of reverse iteration's solution reference is actually to decrease first and then dereference. Otherwise, an error occurs. Imagine if an rp is returned by rbegin (), a null pointer will be operated by directly resolving the reference.
1 # include <iostream> 2 # include <iterator> 3 # include <vector> 4 using namespace std; 5 6/* 7 int main () 8 {9 copy (istream_iterator <int, char> (cin), istream_iterator <int, char> (), 10 ostream_iterator <int, char> (cout ,"")); 11 return 0; 12} 13 */14 15 int main () 16 {17 int casts [10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 18 vector <int> dice (10); 19 copy (casts, casts + 5, dice. begin (); // copy the first five data of casts to d 20 21 ostream_iterator <int, char> out_iter (cout, ""); // create the output stream iterator 22 copy (dice. begin (), dice. end (), out_iter); // copy all the elements in dice to the screen and output 23 24 cout <endl; 25 26/* implicitly use reverse_iterator */27 copy (dice. rbegin (), dice. rend (), out_iter); // returns all the elements in dice to 28 29 cout <endl; 30 31/* explicitly use reverse_iterator */32 vector <int>: reverse_iterator ri; 33 for (ri = dice. rbegin (); ri! = Dice. rend (); ++ ri) 34 cout <* ri <":"; 35 cout <endl; 36 37 return 0; 38} 39 40/** output */41 1 2 3 4 5 0 0 0 0 042 0 0 0 0 0 0 5 4 3 2 143 0: 0: 0: 0: 0: 0: 5: 4: 3: 2: 1:

 

Many algorithms in STL are similar to the copy function. There are three types of insert iterator operations: back_insert_iterator inserts elements into the container tail; front_insert_iterator inserts elements into the container header; insert_iterator inserts an element into a specified position. Compared with the copy operation, the insert operation can automatically increase the space, while the copy operation does not apply to the operating system even if it is not enough, by default, only the data permitted by the capacity is copied. When an iterator is inserted, the container type is used as the template parameter and the container variable is used as the construction parameter, as described below: back_insert_iterator <vector <int> back_iter (dice); For insert_iterator, you also need a construction parameter that specifies the insert position: insert_iterator <vector <int> insert_iter (dice, dice. begin (); [4] The container class container is used to store objects. It requires that the stored objects must have the same type, and the type must be replicable, constructor, and allocable. Generally, both basic and class types meet the requirements (unless you declare these two functions as private or protected ). The requirements for replicable insertion and removable insertion are added in C ++ 11. The container type is the template used to create a specific container. In the past, there were 11 container types: deque/list/queue/priority_queue/stack/vector/map/multimap/set/multiset/biset, and 5 new containers were added for C ++ 11: forward_list/unordered_map/unordered_multimap/unordered_set/unordered_multiset. What is sequence? The sequence ensures that elements are arranged in a specific order and do not change between two iterations. The sequence also requires that its elements are strictly arranged in linear order, that is, the first/second/.../and so on exist. For example, arrays and linked lists are all sequences, but the branch structure is not a sequence. Because the elements in the sequence have a specific order, you can perform operations such as inserting an element to a specific position or deleting a specific range. The following containers are all series containers: vector is a type of representation of arrays. It provides the ability to automatically manage memory and dynamically change the length of the vector to increase or decrease. Vector can be reversed, mainly through rbegin () and rend (), and the returned iterator type is reverse_iterator. Deque dual-end queue. Its implementation is similar to vector and supports random access. The main difference is that you can insert and delete elements from the start and end of deque, and the time complexity is fixed. List two-way linked list. Similar to vector, list can also be reversed. The main difference is that list does not support random access. In addition, the list template class also includes a dedicated member function for the linked list, as shown below: void merge (list <T, Alloc> & x): combines linked list x with called linked list, and ordered. The merged linked list is saved in the called linked list, and x is empty. Void remove (const T & val): removes all instances of val from the linked list. Void sort (): uses the <operator to sort the linked list. The time complexity is nlgn. Void splice (iterator pos, list <T, Alloc> x): inserts the content of the linked list x into the front side of the pos, and x is blank after the insertion. Void unique (): compresses consecutive identical elements in the linked list into a single element. Note: The main difference between insert () and splice () Is that insert inserts a copy of the original range to the target address, while splice transfers the original range to the target address. In C ++ 11, the container class forward_list is added to implement a single-chain table. The associated iterator is a forward iterator rather than a bidirectional iterator. The queue template class is an adapter class. As mentioned above, the ostream_iterator template is also an adapter that allows the output stream to use the iterator interface. Similarly, the queue template class makes the underlying class (deque by default) shows the queue interface. The queue template has more restrictions than deque. It not only does not allow random access, but also does not allow traversal operations. Its usage is restricted to basic queue operations, such as joining, leaving, picking, and determining empty queues. Details are as follows: bool empty () const: true is returned if the queue is empty; otherwise, false is returned. Size_type size () const: returns the number of elements in the queue. T & front (): returns a reference pointing to the first element of the team. T & back (): returns a reference to the element at the end of the team. Void push (const T & x): insert x at the end of the team. Void pop (): deletes the first element of a team. Note: The main difference between priority_queue and queue is that the maximum element is moved to the first of the team. Its internal implementation is vector, which can specify internal element sorting rules. Stack adapter class, implemented using vector, supports the following operations: bool empty () const: returns true if the stack is empty; otherwise, returns false. Size_type size () const: returns the number of elements in the stack. T & top (): return the reference pointing to the top element of the stack. Void push (const T & x): insert x at the top of the stack. Void pop (): deletes the top element of the stack. Array (New in C ++ 11) template class array is not an STL container, because its length is fixed. Therefore, functions such as push_back () and insert () that dynamically adjust the container size cannot be used, but they define useful member functions such as operator [] () and (), as mentioned earlier, many standard STL algorithms can also be used for array objects, such as copy () and for_each (). Operation example:
1 # include <iostream> 2 # include <list> 3 # include <iterator> 4 # include <algorithm> 5 using namespace std; 6 7 void PrintList (int n) {cout <n <"";} 8 9 int main () 10 {11 list <int> one (5, 2 ); // five 212 cout <"list one:"; 13 for_each (one. begin (), one. end (), PrintList); 14 cout <endl; 15 16 list <int> two; 17 int stuff [3] = {2, 5, 9}; 18 two. insert (two. begin (), stuff, stuff + 3); 19 cout <"list two:"; 20 for_each (two. begin (), two. end (), PrintList); 21 cout <endl; 22 23 list <int> three (two); 24 three. insert (three. end (), one. begin (), one. end (); 25 cout <"list three:"; 26 for_each (three. begin (), three. end (), PrintList); 27 cout <endl; 28 29 cout <"merge one and three:"; 30 three. splice (three. begin (), one); 31 for_each (three. begin (), three. end (), PrintList); 32 cout <endl; 33 34 cout <"delete the duplicate elements:"; 35 three. unique (); 36 for_each (three. begin (), three. end (), PrintList); 37 cout <endl; 38 39 cout <"merge with another: four ="; 40 list <int> four (3, 8 ); 41 four. merge (three); 42 for_each (four. begin (), four. end (), PrintList); 43 cout <endl; 44 45 cout <"remove the value 8 in four:"; 46 four. remove (8); 47 for_each (four. begin (), four. end (), PrintList); 48 cout <endl; 49 50 return 0; 51} 52 53/** output */54 list one: 2 2 2 255 list two: 2 5 956 list three: 2 5 9 2 2 2 2 257 merge one and three: 2 2 2 2 2 5 9 2 2 2 2 2 258 delete the duplicate elements: 2 5 9 259 merge with another: four = 2 5 8 8 8 9 260 remove the value 8 in four: 2 5 9 2

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.