01. Carefully select the container type
Select the container principle: you need to consider the ordering of the elements, whether it is consistent with the criteria, iterator capabilities, element layout, compatibility with C, lookup speed, reference count, insert Delete support for the semantics of things, whether some operations will invalidate iterators, memory allocation policies.
Vector
Need to use random iterators
The layout in the container needs to be compatible with C
Deque
Need to use random iterators
When most are inserted at the head and tail
Inserts in the tail will not be iterators, pointers, references become invalid
String
Need to use random iterators
Mind using reference count counts to avoid using String,rope. string is not feasible
Mind that using swap on a container causes iterators, pointers, and references to become invalid. string is not feasible
List
Requires frequent insertion of deletions in the middle
When most are inserted at the head and tail
Insert deletion of multiple elements requires transactional semantics
Hash
Find speed is a key factor, select Vector-> standard associative container with priority hash-> ordering
Attention to the ordering of elements is not feasible
Sequence container (vector string deque list slist rope)
You need to insert a new element anywhere in the container
Associative containers
Inserting elements anywhere in the container is not feasible
Node-based container (list,slist, associative container, hash)
Rollback capability is required when a single node inserts a delete
Make iterators, pointers, and references the least number of times invalid
Avoid moving the original element in the container when the element is inserted and deleted
Continuous memory container (vector,deque,string)
02. Do not attempt to write code that is independent of the container type
Reason:
- Different sets of functions for different containers
- Different containers with the same name function return values differ
- Different containers make iterators invalid rules
- The code you write can only use the intersection of these containers
03. Ensure that the objects in the container are copied correctly and efficiently
Note the point:
- The container that holds the base class object into which the derived class object is inserted results in stripping.
- A simple way to make copy actions efficient, correct, and prevent stripping problems is to include pointers in the container instead of objects.
04. Call empty instead of checking if size () is 0
Reason:
- Using the empty performance is better than judging if size () is 0
- Empty is a constant time, and some list implementations may be linear time
- Only one of the list's size () and splice () can be implemented as a constant time.
05. The interval member function takes precedence over the corresponding single element member function
Legacy Issues:
How to implement Vector::assign
Conclusion:
All copy calls that use an insert iterator to qualify a target interval can be replaced by calls to the interval member function.
Use interval functions to avoid frequent calls to sub-allocations and improve performance.
The interval member functions are: constructors, interval insertions, interval deletions, interval assignments.
06. Beware of the most annoying parsing mechanisms of the C + + compiler
Initialization operation with standard input device
The following are the wrong wording:
std::d eque<int> C (std::istream_iterator<int> (std::cin), std::istream_iterator<int> ());
The above c is parsed as a function declaration. The return value is std::d eque<int>, the first parameter type is std::istream_iterator and the parameter name is CIN. The second parameter has no name, the type is a function, does not accept any arguments, and the return value is std::istream_iterator<int>.
The correct wording is as follows:
std::d eque<int> C ((std::istream_iterator<int> (Std::cin)), (Std::istream_iterator<int> ()));
07. If the container contains a pointer created from the new operator, remember to delete the pointer before the container object is destructor
void DoSomething () { vector<widget*> vwp; Do something //for (Vector<widget*>::iterator i = Vwp.begin (); i!= vwp.end (); ++i) Delete *i}
The above code problem: In the Do something part of the exception, will cause the resource leakage, vector dynamic application widget will not be released.
Workaround: Use the SHARE_PTR smart pointer in the Boost library. When an exception occurs, the destructor for the object in the stack is called.
To delete a pointer's copy-function template
Class DeleteObject { template<typename t> void operator () (const t* PTR) const { delete ptr; }}
08. Never create a container object that contains Auto_ptr
09. Carefully select the method to delete the element
Delete specified value
Vector,string,deque:c.erase (Remove (C.begin (), C.end (), value));
List:c.remove (value);
Set,multiset,map,multimap:c.erase (value); Delete based on equivalence (<)
Remove the value of the discriminant to true
Vector,string, Deque:c.erase (Remove_if (C.begin (), C.end (), judge));
for (Seqcontainer<int>::iterator i = c.begin; I! = C.end ();) {if (judge (*i)) {//process *i i = c.erase (*i);
} else ++i;}
list:c.remove_if (judge);
Set,multiset,map,multimap:
Remove_copy_if;c.swap
assoccontainer<int> c;for (Assoccontainer<int>::iterator i = C.begin (); I! = C.end ();)
{if (judge (*i)) c.erase (i++) Else ++i}
Effective STL--container