Preface:
C ++, data structures, algorithms, and these knowledge are essential in the Internet industry job search process. I have never learned these basics and have used them less, for the sake of future rice bowl, take some time to look at these things from now on. This section is the first part of the notes in data structures and algorithm analysis in C ++ (second edition) in the Mark Allen Weiss Data Structure book ), this part mainly explains some knowledge about C ++, such as object-oriented concepts, inheritance, polymorphism, overloading, virtual functions, templates, and design patterns.
Chap1:
This chapter mainly describes some basic data types of array, String, struct, and pointer.
64bit win7 + 32bit vs2010 after testing, we found that the memory size occupied by different data types is as follows:
Unsigned char: 1, char: 1, unsigned INT: 4, INT: 4, long: 4, unsigned long: 4
The 32bit system can only indicate that the address of the variable is 32bit (4 bytes) and has nothing to do with the memory size occupied by the content in the address.
A pointer is also seen as an object pointing to an object.
The array stores variables of the same data type. These variables can be struct, and different data types can be used in struct.
Vector replaces the original array, while string replaces the original strings.
Among them, vector and string are first-class objects because they meet common operations. A little different is that vector is a class template, while string is a class.
Vector does not perform a boundary check when it uses array subscript access. To ensure its access scope is within its boundary, the usage is no different from that of a common array.
One reason that reference rather than direct parameters are used during parameter passing is that the overhead of copy parameters can be reduced. However, directly using a reference may change the content of the original variable, so it is generally referenced using a constant (if you do not want the original parameter to be changed ).
There is no object corresponding to a multi-dimensional array in STL, but the mat in opencv seems to have this function, two-dimensional.
C_str in stirng indicates that a char * type is returned, which points to the same content as the original string.
When performing the Declaration operation on Pointer variables, you must ensure that the pointer has been correctly initialized.
Automatic Memory Allocation and dynamic memory allocation are two different concepts. Automatic refers to automatic program execution, dynamic refers to manual execution, and declaration is required and destroyed, the corresponding keywords are new and delete. if PT is a pointer, executing Delete PT only removes the memory that PT points to, and the PT variable still exists.
When pointer transmission is performed, it is in the C language style, and when reference transmission is used, it is in the C ++ language style. When the reference is passed, the address is actually passed in implicitly, and the system will automatically unreference it all the time. The advantage of using the reference is that we only need to add the symbol "&" When declaring and defining the reference. When implementing the function, do not add other conformances. simply use the real variable. You do not need to add other symbols when calling a function.
Because the data types of variables in struct are not exactly the same, we cannot cyclically operate on each of the variables as in the array operation. Struct contains multiple variable types. When passed as a parameter, real-value transmission is generally not used, because this overhead is too large (mainly for parameter replication ).
If PS is a pointer to the struct, and A is a member variable of the struct, then (* PS ). a Indicates the variable A in the access struct, but it looks awkward. Therefore, a "->" symbol is provided in C ++, and the expression is PS->.
Chap2:
The operation type defined in the class cannot exceed the range of data operation types embedded in C ++.
An object is an atomic unit that is inseparable. Class properties: Information Hiding, encapsulation, code reuse, template, inheritance, and polymorphism (as part of inheritance ).
Object-oriented programming: object-oriented programming.
Object-based programming: based on object programming, this idea also has encapsulation, Information Hiding, code reuse and other mechanisms, but does not include polymorphism and inheritance.
This is because when executing the class constructor, all the memory of the variables are allocated in sequence before the initial values of the variables are assigned. Generally, data members of a class have their default value assignment mechanism. To change the default value, you can implement it in the constructor. But some variables, such as the const variable, need to assign the initial value to it when defining it (I .e. allocating memory), but the cost function is to allocate all the memory first, and then assign values, obviously does not meet the const variable initialization requirements. Therefore, the const variable initialization can only be performed in the colon initialization list after the const function. The priority of the const variable is higher than that of the const function ontology. Another example is that there is a data member in the class, and there is no default initialization function, so the class initialization should also be carried out in the initialization list.
The keyword explicit is generally used before the constructor, and is generally a single-parameter constructor, because in C ++, if a class constructor is a single-parameter, it allows a value to be assigned directly to an object of the class. In fact, the system first defines a temporary object of the class and uses the value as the constructor parameter of the class, assign the temporary object to the new class object. If the explicit keyword is used, the system (compiler) will no longer allow direct assignment of numbers to class objects.
Const is mainly used in three places: When a function parameter is passed, the return value of the function is placed behind the brackets of the function parameter.
In the class, destructor, copy constructor, and value assignment operator are called Big Three. These three functions have a default implementation in the system, in general, we do not need to change it.
The Destructor mainly releases the variables in the class. These variables include the ones defined in the constructor and other member functions, and all the variables after using new in the class, it also closes all opened documents.
* This indicates the current object.
When the data member of the class has pointer variables, the Big Three needs to be rewritten in general. The Destructor must use Delete to retrieve the corresponding pointer variable. The copy constructor must perform the deep copy operation.
Put the variables whose values need to be initialized in the initialization list as much as possible to avoid additional assignment overhead, because the initialization process for variables that no longer initialize the list is initialized in the 0-parameter constructor. If you re-initialize the variable in the Self-loaded constructor body, this is equivalent to two assignments, and may cause some memory problems (the above understanding may be problematic ). The initialization sequence of data members is not based on the initialization list, but in the order declared in the class. Therefore, we should avoid defining variables that are mutually dependent.
In the following cases, data members must initialize in the initialization list: constants, referenced variables, and variables without the 0-parameter constructor.
A common mistake in C functions is to return a pointer (inside the function) to a dynamic variable. A common mistake in C ++ functions is to return a reference to a dynamic variable.
In C ++, the following five operators cannot be overloaded :".",".*","? : ",": "," Sizeof ". in addition, when an operator is overloaded, only the existing operators in C ++ can be reloaded. New operators cannot be reloaded, and the number of parameters cannot be changed during the reload. In general, the syntax and priority of an overloaded operator cannot be changed.
Because of the class information hiding feature, its private variables cannot be called by class objects. They can only be called by internal member functions, however, if a function is a friend function of this class (generally, this function is not a member function of this class, but an external function ), in this function, all the Members in the class can be called. The actual usage is as follows: when the object B of Class A is passed into function F as a parameter (the user of Class A includes tax), all the members of Class B can be called within function f, including its private members (normally, Private Members cannot be called when their objects ).
Generally, you can use global functions, static class member variables, and enumeration class variables to replace the functions.
Error handling is a difficult problem in the design of C ++ classes. Generally, exception handling mode is used. Exception Handling is commonly used by try-catch statements. Try indicates a test, because the Code implemented in try may have common-sense errors, add non-logical errors in the try statement and throw an integer (other types of values are acceptable). This integer can be understood as the error code. Then, after the try statement, the catch function is connected directly (without semicolons). This function carries parameters that can be of any data type. If you do not know the type, the general symbol "…" can be used. Then implement the corresponding error handling program in the catch statement.
The system automatically calls New [], which generally occurs in constructors. The value assignment operator is =, + =, and the system calls Delete [], which generally occurs in destructor.
If a reference is returned for a function value, an alias is returned. If a constant reference is returned, the alias (the value) returned on the surface cannot be modified.
When the operator is overloaded, the function name is Operator +, operator-, and so on, that is, operator and operator are combined.
The difference between copy constructor and operator = is that when operator = is used, the objects on both sides of the value assignment symbol have been created, and each element is assigned a value. The copy constructor mechanism is mainly used to construct the copy function. function parameters are passed as values, and function return values are also values.
Chap3:
Class templates are mainly used for reuse of code. It is generally applicable to scenarios with independent types.
Templates are divided into function templates and class templates. The general algorithm is implemented in the template. The simple idea of the template is to define a general type with typedef, and then implement the function with the general type.
When using a function template, you must declare the target before use. Generally, the template <class anytype>
The Declaration process is enclosed in angle brackets, and no plus points are added to the end. The implementation process of the function or class is directly followed. anytype indicates the types that can be recognized in the template, in addition, the number of classes in the target is generally not too large. One to two are the most common.
The basic principle of using a class template is the same as that of a function template, but there are three points to note: 1. before the implementation of the class, you also need to add the preceding template declaration statement, and when you implement the member functions in the class outside the class, if you use the class template parameter anytype, before implementation of each function, you must add the class template declaration. 2. in addition to adding the class template declaration statement, you must add the class template parameter <anytype> before the class operator. 3. when initializing an object with a class with a template, you must specify a parameter for the class template parameter, which is also enclosed by Angle brackets.
The purpose of a class template is to implement a common class, so that the desired function can be completed when different types are passed in, reflecting the reusability of the Code. However, there is also a template called a special template, that is, it only applies to a specific type, its class template declaration statement is: Template <>, Which is empty. This method is generally followed by a general class template. Because its template parameter is null, the template must pass the specific type when implementing the class. In this way, when a target class is created, if it belongs to a specific type (that is, a special template), it will be processed according to the special template, otherwise it will belong to a general template.
The implementation code of class templates in earlier versions is also put in. in the H file, some problems may occur during separate compilation, and the class template declaration must be added before the corresponding CPP file implements each function.
The class template has default parameters, or multiple parameters.
Chap4:
Common relationships between classes are IS-A, has-. The class inheritance belongs to is-.
A pointer or reference to a base class can point to its subclass object.
When public inheritance is performed, the hidden attributes of the parent class remain unchanged in the subclass. When private inheritance is performed, all the members of the parent class are private in the subclass. Even if it is a public inheritance, the constructor and destructor of its parent class cannot be inherited by the quilt class. However, when the child class is objectized, the parent class is used, therefore, the parent class must be created first. At this time, the constructor of the parent class will be used, but when the child class is destroyed, the sub-class destructor will be executed first, then execute the destructor of the parent class.
When any member of the parent class is placed in the private area of the subclass, it indicates that these Members cannot be used in the subclass. If they are placed in the public area, you need to overwrite and re-implement these members.
The protected member of the class is only open to itself and its sub-classes, and not to other classes.
In the initialization list of the subclass constructor, you can call the base class constructor directly by using the function name. If the content of the constructor body of the subclass is empty, the constructor of the parent class is used directly.
The design of the subclass generally does not need to consider the Private Members of the parent class. Therefore, the modification of the Private Members in the parent class has no impact on the design of the subclass.
There are two types of rewriting: one is to directly rewrite the member function and the other is to rewrite the virtual function, but only to rewrite the virtual function is to reflect the class polymorphism. The purpose of polymorphism is to achieve interface reuse.
One advantage of a virtual function is that it can directly use the pointer of the parent class to call the corresponding subclass function, instead of using the subclass object. If the subclass does not implement the corresponding virtual function code, the subclass object calls the function content of the parent class.
To realize polymorphism (when a pointer or reference access is used), the virtual keyword should be declared in the parent class, which is invalid in the subclass.
Even if the constructor, destructor, value assignment, and copy constructor in the parent class are put in the public area, and the subclass inherits the parent class in the public mode, if these functions are not redefined in the subclass, the system automatically constructs them using the default method instead of the parent class, because the subclass does not inherit these functions.
In the design of classes, constructor is usually defined as non-virtual, while destructor is defined as virtual.
Classes that contain at least one abstract method (generally called pure virtual functions, followed by "= 0" instead of the function body) are called abstract classes. abstract classes cannot be used to instantiate objects, if its subclass does not implement the corresponding abstract method, it cannot be used to instantiate the object. Therefore, its constructor is usually not used unless it calls to initialize some variables of the parent class. However, you can define a pointer or reference to an abstract class to point to its subclass (non-Abstract subclass ).
The default parameters of a function in the class are all statically bound. Generally, other member functions (virtual functions) are also statically bound.
Function overload: in a class, functions and functions have the same name, different parameter types or numbers, and the return values of functions do not necessarily need to be the same. Only compatible.
Function coverage: In the base class and derived class, the base class function must be a virtual function. The functions in the two classes have the same name as the function, and the parameter type and number are the same, the Return Value Type of the function must be the same.
Function hiding: In the base class and derived class, if the function names of the two classes are the same, function hiding is not applicable to all scenarios where the function coverage is not met.
Public inheritance embodies the IS-A relationship, while private inheritance reflects the HAS-A relationship. In general, use the private inheritance method as little as possible. By default, subclass inheritance is private inheritance. Therefore, when subclass inheritance is non-private inheritance, do not forget to add the corresponding keywords.
In principle, the Friends function of the parent class is not a friend function of the Child class. However, the Friends function of the parent class can access the members that inherit from the Child class.
If you want to embody the class polymorphism mechanism, generally do not pass the object as a value.
The composition mechanism in a class application refers to calling another class object during the implementation of a class code, the most common case is to pass a class object as a parameter to the constructor of another class.
Chap5:
A design pattern is similar to a recipe. It has a pattern name, a description of the problem, a solution to the problem, and a description of the result.
If we want to implement a function with a relatively large size and its parameters must meet various data types, we can implement a comparison operator in each corresponding class "<", in this way, the operator needs to be reloaded every time a class is implemented. Suppose we do not want to implement this function inside the class, we should implement this operator outside the class, But once this operator function is set, there is only one condition that cannot satisfy all types. Therefore, another implementation method is to implement multiple comparison functions outside the class, which is called functor. The general meaning of functor is to use a class object as a function. Of course, this class needs to overload the () operator. He is like a function, so he got a name named funtor, which comes from the commond design pattern. A functor contains only one method and does not contain data members. Therefore, when passing a function as a parameter, it must be passed as a value. Functor is also the function handle that we often call. It can be implemented using classes. In this way, the parameter of the function that completes the comparison is the dataset and the function class.
In the C ++ standard, the wrapper pointer class is named auto_ptr, which automatically deletes the memory dynamically. Generally, the deletion of pointer memory occurs in the following three cases: 1. The local variable of new in the function. 2. The local variable pointer of the new function is used as the return value. The returned pointer is called in another function. When the function called ends, the new memory needs to be released. 3. A pointer after new is passed into a function as a parameter, and the delete parameter pointer is used inside the function. The auto_ptr contains a pointer and an owner indicator variable. if the pointer is the "master", the corresponding pointer memory needs to be deleted during the destructor. If the replication operation occurs, transfer the "master" identity. Therefore, auto_ptr is a pointer wrapper. Constant reference wrapper is mainly used to handle the case where the reference points to null.
Wrapper focuses on packaging, while adapter focuses on conversions between interfaces.
To solve the compilation problem caused by bidirectional type conversion, we try to use the explicit keyword in the class constructor.
A pointer can point to a target or a null object, but a reference can point to only one target, not null.
When two classes are called each other, an incomplete class declaration is required.
The iterator mode is used to solve the traversal problem of an aggregate object and encapsulate the traversal of the aggregate into a class. This avoids exposing the internal representation of the aggregate object. The most direct idea is to traverse a container without considering the element types inside the container.
The iterator must have hasnext and next methods, and the corresponding container has the getiterator type conversion method.
Causes of factory mode: 1. A base class pointer can point to any of its sub-class objects, but every time new is required to create a sub-class, and the sub-class name needs to be known, so that the extension and maintenance of the program will become troublesome. 2. When Class A uses base class B and needs to initialize a subclass of Class B, A does not know which subclass to initialize, but the subclass of Class A knows. Therefore, factory provides two important functions: defining the interfaces for creating classes, encapsulating the creation of objects, and delaying the work of specific classes to subclass. In factory mode, each container can return an iterator pointing to an abstract class.
The composite mode is applicable when a function needs to return multiple parameters (two parameters are the most common). For example, pair and pair are used to construct map and dictionary.
The observer mode mainly solves one-to-many dependencies. When "one" (subject) changes, the corresponding multiple dependencies (obverser) also change accordingly. A common example is that a group of data in an Excel chart can have multiple visual results. When the data changes, the visual results also change. In general, the obverser has an update function.
References:
Data Structures and algorithm analysis in C ++ (second edition), Mark Allen Weiss.
23 design modes (C ++)