C++ operator overloading
Operator overloading is intended to make the operation more mathematically appropriate.
Definition 1.
Operator < an operator >
The principle of 2.
1) Follow the syntax of the existing operators, such as a single entry can only be overloaded into a single entry
2) Follow the semantics of existing operators (but this is not required)
3) Implementation path of operator overloading: it can be a non-static member function of a class, or it can be a global function with class, structure, enumeration, and their reference type parameters
4) Overloaded operators
All but the following five operators can be overloaded
“.” (member selector),”.*” (indirect member selector),”::” (domain resolver),”? :” (conditional operator),”sizeof”
Watch out for memory leaks when operator overloading occurs!!
C++ inheritance
1. public
1) The public member of the base class, and the public member of the derived class
2) Protected members of base classes, and protected members of derived classes
3) A private member of a base class, a member that cannot be used directly in a derived class
2. protected
1) Public members of the base class, and protected members of the derived class
2) Protected members of base classes, and protected members of derived classes
3) A private member of a base class, a member that cannot be used directly in a derived class
3. private
1) Public member of base class, private member of derived class
2) Protected member of base class, private member of derived class
3) A private member of a base class, a member that cannot be used directly in a derived class
C++ inheritance changes
In any inheritance mode, except for the private members of the base class, you can adjust their access control separately in the derived class.
Adjust the format
[public: | protected: | private:] < base class name > : : < name > base class members;
class A { public: void f1(); void f2(); void f3(); protected: void g1(); void g2(); void g3(); } class B: private A { public: A::f1; // change f1 to public A::g1; // Make G1 public, and whether to allow weaker access controls for base classes depends on the implementation. // Change f2 to protected A::g2; } class C: class B {public: void h() {f1(); f2(); g1(); g2(); //OK f3(); g3(); //Error, f3, G3 are private members of base B}}
Dynamic binding of C++ messages (member function calls)
1. Message polymorphism
C++ treats classes as types and derived classes inherited in public (strictly speaking: public only) as subtypes of the base class. This results in the following three polymorphisms in C++ object-oriented programs:
1) Polymorphism of object types: The type of a derived object can be either a derived or a base class.
2) Polymorphism of object flags: Pointers or references to base classes can point to or refer to base objects, as well as objects of derived classes. (A pointer to a derived class can only point to or refer to a derived object, not to a base object.)
3) Polymorphisms of messages, a message that can be sent to a base class object or to a derived class object.
2. Static binding
The type of data bound at compile time. (the default)
3. Dynamic binding
The type of data bound at run time.
class A { int x,y; public: void f(); } class B: public A { int z; public: void f(); void g(); } void func1(A& x) { x.f(); // call A::f, because C++ is static binding} void func2(A* p) {p->f(); // call A::f, because C++ is statically bound}
3. Dynamic binding of virtual functions to messages
1) Definition of virtual function
Add virtual before the function return type
class A {… public: virtual void f(); // virtual function}
Limitations: a. Only member functions of a class can be virtual functions
B. Static member functions cannot be virtual functions
C. Constructors cannot be virtual functions
D. Destructors can be (often) virtual
2) Dynamic binding of virtual functions
If a member function in a base class is defined as a virtual function, the member function of the same type defined in the derived class is a redefinition (or override) of that base class member function.
Identical construction: A derived class that has the same function name, the same parameter type and number, the same return value type, or the return value type of a member function of a base class
class A { int x; public: virtual void f(); } class B: public A { int y; public: void f(); void g(); } A *p = new B; p->f(); //OK, call B f p->g(); //Error, because A does not have g((B*)p)->g(); //OK, call g of B
C++ pure virtual functions and abstract classes
1. Pure virtual functions
Define format: use the symbol “=0” after the function prototype
class A
{
.
public:
virtual int f()=0;
}
2. An abstract class
Classes containing pure virtual functions become abstract classes, used to provide a basic framework and a common interface to the outside world for derived classes (or derived classes of derived classes…). , all pure virtual member functions of the abstract base class should be implemented. (The form is similar to Java abstract class, function is similar to Java interface)
C + + multiple inheritance
1. Define the format
Class < name > derived class: [< > inheritance way] < 1 > base class name, [< > inheritance way] < 2 > base class name,…
{< member description table >
};
2. Repeated inheritance — virtual base classes
In multiple inheritance, repeated inheritance occurs if the immediate base class has a common base class. Thus, data members in a common base class have multiple copies in multi-inherited derived classes.
Such as:
class A { int x; }; class B: public A{}; class C: public A{}; class D: public B, public C{}; B::x and C::x
To solve such problems, use virtual base classes.
1) The constructor of the virtual base class has the constructor call of the newly derived class
2) Virtual base class constructors take precedence over non-virtual base class constructors
class A
{
int x;
public:
A(int i) {x=i; }
};
class B: virtual public A
{
int y;
public:
B(int i): A(1) {y=i; }
};
class C: virtual public A
{
int z;
public:
C(int i): A(2) {z=i; }
};
class D: public B, public C
{
int m;
public:
D(int i, int j, int k): B(i),C(j),A(3){m=k; }
};
class E: public C
{
int n;
public:
E(int i, int j, int k, int l): D(i,j,k),A(4){n=1; }
}; D D (1, 2, 3); E E (1, 2, 3, 4);
When D object D is created, the constructors are called in this order:
A (3), B (1), C (2), D (1, 2, 3);
When E object E is created, the constructors are called in this order:
A(4), B(1), C(2), D(1,2,3), E(1,2,3,4)
C + + template
1. The class attribute
Class attribute: A feature of a program entity that can manipulate or describe multiple types of data.
Generic function: a function that performs the same operation on different types of data (parameters).
Generic class: A class whose members are of variable type.
2. Function templates
Dynamic languages do not specify types when defining parameters, so they have class attributes themselves.
C++ is a statically typed language that can implement class attributes through macro definitions, pointer type parameters, function templates, and so on.
3. Pointer type parameters
Define the parameter type as void *, because void * can accept any pointer type.
But this way is not readable, and implementation trouble, generally not.
4. Function templates
define
template <class T1, class T2, … >
< return value type > < function name > (< parameter list >)
{… }
instantiation
Implicit: The compiler automatically instantiates a function template as a concrete function based on the type of argument at call time.
Explicit: sort < int > (a, 100); sort<double>(b,100); Etc.
It can also be of a specific type:
template <class T, int size>
void fun (T a)
{… }
f<int, 10>(a);
5. Class templates
template <class T1, class T2, … >
Class < class name >
{< class member declaration >
};
A member function defined outside the class
template <class T1, class T2, … >
< return value type > < class name > <T1, T2… >::< member function name >(< parameter list >){… }
C++ standard template library
1. The container
Containers are used to store data elements, which are sequences of elements of the same type with variable length (number of elements), such as vectors, sets, stacks, queues, and so on.
Vector < element type > : used to quickly locate (access) elements in arbitrary locations and to add/remove elements primarily at the end of a sequence of elements. Defined in a vector header and implemented as a dynamic array.
Map < keyword type, value type > and multimap< keyword type, value type > : Elements are sorted by keyword. The keys of different elements in a multimap can be the same, defined in the map header and often implemented in some kind of binary tree.
Set < element type > and multiset< element type > : defined in the set header, set can be used for de-duplication.
Basic_string < element type > : Similar to vector except that its element type is a character and provides a series of string-related operations. Basic_string <char> and basic_string<wchar_t> are its two instances. Defined in the string header file.
List < element type > : used when elements are frequently inserted/deleted anywhere in a sequence of elements. Defined in the list header and implemented as a two-way linked list.
Deque < element type > : Used primarily to add/remove elements at both ends of a sequence of elements and to quickly locate (access) elements at arbitrary locations. In the deque header file definition, using a segmented continuous space structure implementation.
Stack < element type > : used to add/remove elements only at the end of a sequence of elements, defined in the stack header file, generally implemented based on a deque.
Queue < element type > : used to add elements only at the end of an element sequence and remove elements at the head. Defined in the queue header and typically implemented in a deque.
Priority_queue < element type > : The operation is similar to that of queue, except that after each increment, the position of the element is adjusted so that the header element is always the largest. That is, the largest element is always deleted. Defined in the queue header and typically implemented using vector and heap structures.
2. The iterator
Iterators implement abstract Pointers (smart Pointers) that point to elements in a container and are used for accessing and traversing elements in the container.
Input iterator: can only be used to read the container element to which it refers.
Output iterator: Can only be used to modify the container element to which it refers.
Forward iterator: Can be used to read and modify the container element to which it refers.
Bidirectional iterators: Can be used to read/modify the container element to which it refers.
Random-access iterator: Can be used to read/modify the container element to which it refers.
3. The algorithm
Reordering algorithm: Changes the order of elements in a container. Such as sort reverse random_shuffle
Edit algorithm: used to copy, replace, delete, exchange, merge, and assign container elements. Copy replace remove unique swap
Lookup algorithm: Used to find elements or sequences of child elements in a container. For example, find count Search
Arithmetic algorithm: used for summation, inner product sum, difference, etc. of elements in a container. Such as accumulate partial_sum inner_product
Set algorithm: Operations used to implement sets. Such as include set_union set_intersection
Heap algorithm: used to store and manipulate elements in a container in pairs. One of the main characteristics of a heap container is that the first element is always the largest. Such as make_heap pop_heap, etc
Element traversal and manipulation algorithm: Accesses each element in a range in turn and calls some specified operation function or function object f for each element. for_each
C++ exception handling mechanism
void f() { … . throw 1; . . Throw 1.0; . . throw “abcd”; . } int main() { … try { f(); } catch(int){} catch(double){} catch(char*){} }