#类的this
Suppose there is a class a,total is an object of A, and ISBN () is a member of a function when we use the
TOTAL.ISBN (), you are actually calling ISBN () for an object. The member function accesses the object that invokes it through an additional implicit function called this. When we call a member function, it is initialized with the object address of the function that requested it, for example:
Called TOTAL.ISBN (), the compiler is responsible for passing the address of total to the implicit formal parameter of the ISBN, which can be considered as equivalent
A::ISBN (&total)
Because the purpose of this is always to point to "this" object, this is a constant pointer to a *const this, that is, the address of this point cannot be changed
So what if you want this to be a const a *const this? This is implicit and does not appear in the parameter list, where do you want to declare it?
The C + + approach is to allow the const to be placed after the parameter list of the member function, which indicates that this is a pointer to a constant, so that the member function using const is also called a constant member function
Because this is the const a *const, it is not possible to change the contents of the object that invokes it in this function.
Constant object, a reference to a constant object, or a pointer can only call a constant member function
The compiler processes the class by first compiling the declaration of the member and then the body of the member function, so the member function body is free to use the other members of the class without being concerned about the order of the members.
The name of the member defined outside the class must contain the class name to which it belongs.
#构造函数
Classes control the initialization of their objects through one or several special member functions, called constructors.
The constructor has the same name as the class name and no return type.
Constructors cannot be declared as const, and when we create a const object, the object can get the "Const" property until the constructor finishes the initialization process.
Only the class does not explicitly define a constructor, and the compiler implicitly defines a default constructor for us.
If a class contains a member of another class type and the type of the member does not have a default constructor, the compiler cannot initialize the member.
A list of constructor initial values.
#拷贝, assignment and destruction
#访问控制与封装
Public: Members can be accessed throughout the program, defining the interface of the class
Private: Members can be accessed by member functions of the class, encapsulating the implementation details of the class
A class is not qualified for the number of times an access descriptor can occur.
# #我们可以使用class或struct定义类, the only difference is that the default access rights for struct and class are not the same.
# #类可以在它的第一个访问说明符之前定义成员, access to such a member depends on how the class is defined.
# #使用struct, the default is public
# #使用class, the default is private
#友元
A class can allow other classes or functions to access its non-common members by making other classes or functions its friend, adding a function declaration statement that begins with the Friend keyword in the class. Remember that a friend declaration can only appear inside a class definition.
Adding the mutable keyword to the declaration of a variable inside a class indicates that this is a mutable data member, and that a mutable data member is never const, even if it is a member of a const object, so a const member function can change the value of a mutable data member.
# #一个const成员函数如果以引用的方式返回 *this, then its return type is a constant reference.
Therefore, const-based overloads are often used.
For a class, it must be defined before we create its object, not just a declaration, or the compiler cannot determine how much storage space such an object requires.
The definition of a member function is not processed until the compiler finishes processing all declarations in the class.
When the constructor of a class executes, if the member is const, referenced, or belongs to a class type that does not provide a default constructor, it must be initialized through the constructor initializer list and cannot be assigned a value in the function body.
The constructor initializer list only describes the values that are used to initialize the members, not the specific order in which the initialization is performed.
The initialization order of the members is consistent with the order in which they appear in the class definition: The first member is initialized first, and then the 2nd one ...
#委托构造函数
The delegate constructor performs its own initialization process using the other constructors of the class that it belongs to.
Way: There is only one entry in the member initialization list, and other constructors are called.
Conversion constructors
#类的静态成员
Static
Static members can be public,private, constants, references, pointers, class types, etc.
A static member of a class exists outside any object, and the object does not contain any data related to a static data member.
Similarly, static member functions are not bound to any objects, and they do not contain the this pointer.
Therefore, a static member function cannot be declared as const, nor can it be used within the static function body.
Use the scope operator to access static members directly.
Although static members do not belong to an object of the class, we can still use the object, reference, and pointer of the class to access the static members.
#顺序容器
A container is a collection of certain types of objects.
Container operation:
Iterator type of iterator for this container type
Const_iterator can read elements, but cannot modify the iterator type of an element
C.insert (a) Copy the elements of A into C
C.emplace (a) using an element in a construct C
C.begin () C.end ()
C.cbegin () c.cend () return const_iterator
C.rbegin () C.rend ()
The swap function is used on the container, constant time, because the element itself is not exchanged, but the internal data structure of 2 containers is exchanged.
# #容器操作可能会使迭代器失效
An invalid pointer, reference, iterator will no longer represent any element.
Instead of defining member functions for each container, the standard library container implements a set of generic algorithms that are mostly independent of any particular container and are generic.
# #unique, go heavy, but no real delete element, just overwrite adjacent repeating element, make
# #不重复元素出现在序列开始的部分, the value of the element after the position is unknown
# #比如unique (A.begin (), A.end ())
# #返回指向不重复区域之后一个位置的迭代器
#lambda表达式
You can interpret a lambda expression as an unnamed inline function
# #与函数相同之处: Has a return type, a parameter list, a function body
# #与函数不同指出: Lambda may be defined inside a function
# #形式
##[capture list]/(parameter list/)->return type/{function body/}
# #python的形式是: Lambda x:f (x)
# #capture list, the Capture list, is a listing of the local variables defined in the function where the lambda is located, often empty
# #可以忽略参数列表和返回类型, but capture list and function body cannot be ignored
Auto F = [] {return 42;}
Called using the call operator just like a normal function: f ()
The parameter list for lambda cannot have default parameters
[]/(const string &a,const string &b/) {return a.size () < B.size ();}
# #一个lambda只有在其捕获列表中捕获一个它所在函数中的局部变量 to use the variable in the body of the function.
# #捕获列表只用于局部非static变量, a lambda can use a local static variable directly and a name declared outside of its function.
# #捕获方式可以是值或引用.
# #值捕获时, unlike function parameters, the value of the captured variable is copied when the lambda is created, not when it is called.
# #引用捕获时, using the object that the reference is bound to. In this case, the drug guarantees that the variable persists while lambda is executing.
# #可以从一个函数返回lambda.
Implicit capture: You can have the compiler infer the variables we use based on the code in the lambda body.
[=] Take value capture
[&] using reference capture
By default, for a variable whose value is copied, the lambda does not change its value, and if you want to change the value of a captured variable, you must add the mutable keyword to the argument list.
#动态内存
The lifetime of dynamically allocated objects is irrelevant to where they were created, and they are destroyed only when explicitly disposed.
New allocates space for the object in dynamic memory and returns a pointer to the object.
Delete takes a pointer to a dynamic object, destroys the object, and frees the memory associated with it.
2 Smart pointers, responsible for automatically releasing the objects that you point to.
#拷贝控制
Copy constructor, copy assignment operator
Move constructor, move assignment operator
Destructors
# #拷贝构造函数
If the first parameter of a constructor is a reference to its own class type, and any additional arguments have default values, this constructor is a copy constructor.
The first parameter of a copy constructor must be a reference type.
In general, the copy constructor synthesized by the compiler copies the non-static members of its parameters to the object being created one by one.
The type of each member determines how it is copied: for a member of a class type, its copy constructor is used, the members of the built-in type are copied directly, although the array cannot be copied directly, but the composite copy constructor copies the members of an array type element-wise.
What happens when the copy is initialized:
Define Variables with =
To pass an object as an argument to a parameter of a non-reference type
Returns an object from a function that returns a type other than a reference type
Initializes an element in an array or a member of an aggregation class with a list of curly braces
Some class types also use copy initialization for the objects they are assigned to.
# #拷贝构造函数被用来初始化非引用类类型参数, this feature explains why a copy constructor's own argument must be a reference type
Because if its argument is not a reference type, the call never succeeds-in order to invoke the copy constructor, we must copy its arguments, but in order to copy the arguments, we need to call the copy constructor, an infinite loop.
Like the copy constructor, if the class does not define its own copy assignment operator, the compiler will synthesize one for it.
Overloaded operators are essentially functions, as well as a return type and a list of parameters.
# #赋值运算符通常返回一个指向其左侧运算对象的引用.
# #析构函数
The destructor frees the resource used by the object and destroys the object's non-static data members.
# #名字由 ~ Class name purchased, no return value, no parameters accepted.
Because destructors do not accept parameters, they cannot be overloaded.
In a destructor, the function body is executed first, and then the member is destroyed. Members are destroyed in reverse order of initialization.
# #隐式销毁一个内置指针类型的成员不会delete它所指向的对象.
# #当指向一个对象的引用或指针离开作用域时, destructors do not execute.
Whenever an object is destroyed, its destructor is automatically called.
The destructor body itself does not destroy members directly, and the members are destroyed after the destructor body is suppressed at the time of the destructor.
# #定义删除的函数
We can block the copy by defining the copy constructor and copy assignment operators as deleted functions: Deleted function is one that we declare, but we cannot use them in any way. Add =delete to the function's argument list to indicate that we want to define it as deleted.
If the destructor is defined as deleted function, this class object cannot be destroyed.
If a class has data members that cannot be constructed, copied, copied, or destroyed by default, the corresponding member function is defined as deleted.
You can also block copies by declaring their copy constructors and copy assignment operators as private.
When writing an assignment operator, you need to be aware that:
If you assign an object to itself, the assignment operator must work correctly.
Most assignment operators combine the work of destructors and copy constructors.
#重载运算与类型转换
The overloaded operator is a function with a special name: the operator + operation symbol makes up the name.
Of course also contains the return type, parameter list, function body.
Overloaded operators have as many arguments as the operators do, and the explicit parameters are less than the total number of member functions.
Because its left-hand operand is bound to the implicit this pointer.
Except for operator (), other overloaded operators cannot have default arguments.
For an operator function, it is either a member of a class, or at least a parameter of a class type.
Only existing operators can be overloaded, and new operators cannot be invented.
+-*& is both a unary and two yuan, which operator can be inferred from the number of parameters.
When we define an operator as a member function, its left operand must be an object of the class to which the operator belongs.
Typically, the << first parameter of the output operator is a reference to a very ostream object, which is very much because the stream writes the content to change its state, which is a reference because we cannot copy a Ostream object directly.
# #输入输出运算符必须是非成员函数.
Assuming that the input and output operators are members of a class, they must also be members of IStream and Ostream, but these 2 classes belong to the standard library, and we cannot add any members to the classes in the standard library.
# #输入运算符必须处理输入可能失败的情况, and the output operator is not required.
The subscript operator [] must be a member function.
Overloads of the increment decrement operator have both pre-and post-build versions, and the functions are:
A &operator++ () {}
So there is no way to overload, because there is no way to differentiate the overload, in order to solve this problem, the post-build accepts an additional non-used int type parameter, when we use the post operator, the compiler provides a value of 0 for this parameter argument. Although it is syntactically possible for a function to use this parameter, it is not used in the actual process. Because the only function of this parameter is to differentiate between pre-and post-version functions.
# #前置一般返回的是一个引用, the back is generally returned as a value.
# #函数调用运算符
If the class overloads the function call operator, we can use the object of that class as if it were a function.
Operator ()
The function call operator must be a member function.
If a class defines a call operator, the object of that class is called a function object.
# #lambda是函数对象
When we have written a lambda, the compiler translates the expression into an unnamed object of an unnamed class that contains an overloaded function call operator in the class that the lambda expression produces.
For a capture list of lambda, if it is a value capture, in the form of a data member of the class in the class, if it is a reference capture, the compiler can use the reference directly.
A lambda expression produces a class that does not contain a default constructor, an assignment operator, and a default destructor.
C + + Callable objects: functions, function pointers, lambda expressions, bind-created objects, overloads of class for function call operators.
# #类类型转换
Conversion constructors and type conversion operators
A type conversion operator is a special member function of a class that is responsible for converting a value of a class type to another type
operator type () const;
The type conversion operator is defined for any type (except void) and, as long as the type can be used as the return type of a function, it is not allowed to convert an array or function type, but is allowed to be converted to a pointer or reference type.
The class type conversion operator does not have an explicit return type, has no formal parameters, and must be defined as a member function of a class.
# #类型转换运算符是隐式执行的, so arguments cannot be passed
# #显式的类型转换运算符
Explicit operator type () const;
The compiler typically does not use an explicit type conversion operator for implicit type conversions
When the type conversion operator is explicit, we can also perform a type conversion, but it must be done by explicitly forcing the type conversion.
Exception: When an expression is used as a condition, the compiler automatically applies the explicit type conversion to it.
#面向对象程序设计
3 Basic concepts: Data abstraction, inheritance, dynamic binding.
Data abstraction: Separating the interface and implementation of a class
Inheritance: Similar relationships
Dynamic binding: To some extent ignoring the differences of similar types, using their objects in a uniform manner
# #继承
The classes that are linked by inheritance are purchased as a hierarchical relationship. Usually there is a base class at the root.
Other classes inherit directly or indirectly from the base class, and the inherited classes are called derived classes (derived class).
The base class is responsible for defining members that are common to all classes in a hierarchical relationship, and each derived class defines its own unique members.
For some functions, the base class expects its derived classes to each define a version that is appropriate for itself, when the base class declares these functions as virtual functions (virtual function).
A derived class must explicitly indicate which base class it inherits from by using the class derivation list.
Form: A colon after the class name:, followed by a comma-delimited list of base classes, preceded by an access specifier (public,private, etc.)
The derived class must declare all the redefined virtual functions within it.
# #C + +, dynamic binding occurs when we call a virtual function using a reference or pointer to a base class
A class that is a root node in an inheritance relationship typically defines a virtual destructor, even if the function does not perform any actual operations.
# #任何构造函数之外的非静态函数都可以是虚函数.
Virtual can only appear before a declaration statement inside a class and cannot be used for function definitions outside the class.
# #如果基类把一个函数声明为virtual, the function is implicitly also virtual in the derived class
If a member function is not declared as a virtual function, its parsing process occurs at compile time rather than at runtime.
A derived class can inherit a member defined in a base class, but a member function of a derived class does not necessarily have permission to access a member inherited from a base class.
# #派生类能访问public, protected, but cannot access private
# #如果派生类没有覆盖其基类中的某个虚函数, the virtual function behaves like other ordinary members, and the derived class directly inherits its version in the base class.
# #派生类到基类的转换 (compiler implicitly executes)
We can use the object of a derived class as a base class object, or you can bind a pointer or reference to a base class on the base class part of a derived class object.
Although derived class objects contain members that inherit from the base class, derived classes cannot initialize these members directly, and they need to be initialized with the constructor of the base class.
# #每个类控制它自己的成员初始化过程.
Derived classes can access the public and protected of the base class
# #如果基类定义了一个静态成员, there is only a unique definition of the member in the entire inheritance system, no matter how many derived classes derive from the base class, there is only one instance for each static member.
# #一个类不能派生它本身.
# #C ++11, if we don't want to have a class as a base class, we can add the final to the class name defined by the class
Class A final {};
The automatic type conversion of a derived class to a base class is valid only for pointers or reference types, and there is no such conversion between the derived class type and the base class type.
When we initialize or assign a value to a base class object using a derived class object, only the portion of the base class in the derived class object is copied, moved, or assigned, and its derived class portion is ignored.
# #虚函数
In C + +, dynamic binding is performed when we invoke a virtual member function with a reference or pointer to a base class, because we know that the runtime knows which version of the virtual function is called, so all virtual functions must be defined.
When a virtual function is called through a pointer or reference, the code produced by the compiler cannot determine which version of the function should be called until run time, and the function being called is the one that matches the dynamic type of the object bound to the pointer or reference.
# #动态绑定只有当我们通过指针或引用调用虚函数的时候才会发生.
If a function of a derived class overrides an inherited virtual function, its formal parameter type must be exactly the same as the base class function it overrides. However, when a class's virtual function return type is a pointer or reference to the class itself, the exception.
If a derived class defines a function that has the same name as a virtual function in the base class but differs from the formal parameter list, the compiler will assume that the newly defined function is independent of the functions in the base class.
# #override
# #final
If we have defined the function as final, then any subsequent attempt to overwrite the function throws an error.
The override and final specifiers appear after the formal parameter list.
Virtual functions can also have default arguments. If a function calls the default argument, the argument is determined by the static type of the call.
If we want to make a call to a virtual function not to bind dynamically, but rather to force a particular version of a virtual function, using the scope operator can do this.
# #pure Virtual
A pure virtual function is not defined, we can describe a virtual function as pure virtual function by adding =0 before the semicolon of the declaration statement.
##=0 can only appear within a virtual function declaration statement inside a class, and the function body of a pure virtual function must be defined outside the class if it is to be defined.
In other words, we cannot provide a function body within a class for a function of = 0.
Classes with or without overrides that directly inherit pure virtual functions are abstract base classes, and abstract base classes are responsible for defining interfaces, and subsequent classes can overwrite the interface. We cannot directly create an object of an abstract base class.
# #在一个派生类内部, the derived class access specifier has no effect on the members of the derived class and on whether a friend can access its immediate base class, and access to the base class member is only related to the access specifier in the base class.
# #派生访问说明符的目的是控制派生类用户对于基类用成员的访问权限.
# #不能继承友元关系, each class is responsible for controlling the access rights of its members.
#using语句还可以改变访问权限, a variety of rules.
# #默认情况下, derived classes defined using the class keyword are private inheritance, and derived classes defined with the struct keyword are public-inherited.
# #函数调用的解析过程
If we call P->mem (), or Obj.mem (), Step:
1. First determine the static type of P or obj, because a member is called, so the type must be a class type.
2. Find the mem in the class corresponding to the static type of P or obj, and if it is not found, continue to find in the direct base class until it reaches the top of the inheritance chain, and if it still cannot be found, the compiler will error.
3. If MEM is found, perform a regular type check to confirm that the call is legitimate for the currently found MEM
4. If the call is legitimate, the compiler produces different code depending on whether the call is a virtual function:
If the mem is a virtual function && is called by reference or pointer, the compiler-generated code determines at run time which version of the virtual function is running, based on the object's dynamic type.
If the mem is not a virtual function or is a call made through an object, the compiler produces a regular function call.
The virtual properties of the destructor are also inherited.
# #如果基类的析构函数不是虚函数, delete a base-class pointer to a derived class object will produce undefined behavior
Objects are destroyed in the reverse order that they are created, and the derived class destructor executes first, then the destructor of the base class.
#模板与泛型编程
A function template is a formula that is used to generate a version of a function for a specific type.
template< TypeName T> or
template< class T>
Same meaning, a template parameter list can also use both TypeName and class
Template parameter list cannot be empty in template definition.
The actual type of T is determined at compile time based on the usage of compare.
When we invoke a function template, the compiler usually uses the function arguments to infer the template arguments for us.
The compiler then infers the template parameters to generate a specific version of the function for us.
These compiler-generated versions are often referred to as instances of templates.
You can also define non-type parameters in a template, a non-type parameter represents a value instead of a type, and we specify a non-type parameter by a specific type name.
When the compiler encounters a template definition, it does not generate code, and the compiler generates code only when we instantiate a specific version of the template.
The definition of function templates and class template member functions is usually placed in the header file.
Each instance of a class template forms a separate class.
As with any other class, we can define member functions for it inside the class template and outside of the class template, and the member functions defined within the class template are implicitly declared as inline functions.
By default, a member function of a class template is instantiated only when it is used by the program.
When a class contains a friend declaration, whether the class and the friend are each a template is irrelevant, if a class template contains a non-template friend, the friend is authorized to access all template instances, if the friend itself is a template, the class can be authorized to all friend template instances, or can only be authorized to specific instances.
"C + + primer 5th" notes