C + + improve notes

Static member

Type preceded by static

Static member variable

All objects share the same data
Allocate memory at compile time and declare in class
Out of class initialization

Static member function

All objects share the same function
Static member functions can only access static member variables

Private permissions are also inaccessible

C + + object model and this pointer

Member variables and member functions are stored separately
Member variables and member functions in a class are stored separately. Only non static member variables belong to the object of the class

Non static member variables occupy object space
Static member variables do not occupy object space
Member functions (static / non static) also do not occupy object space

this pointer concept

Each non static member function will only produce a function instance, that is, multiple objects of the same type will share a piece of code

So the question is: how does this piece of code distinguish that object from calling itself?

c + + solves the above problems by providing special object pointer and this pointer. The this pointer points to the object to which the called member function belongs

this pointer is a pointer implied in each non static member function

this pointer does not need to be defined and can be used directly

Purpose of this pointer:

When a formal parameter has the same name as a member variable, it can be distinguished by the this pointer
Return the object itself in the non static member function of the class. You can use return *this

Null pointer access member function

C + + hollow pointer can also call member functions, but pay attention to whether this pointer is used
If this pointer is used, it needs to be judged to ensure the robustness of the code

if (this == NULL) {
	return;

const modifier member function

Constant function:

After adding const to a member function, we call this function a constant function
Member properties cannot be modified within a constant function
After the keyword mutable is added to the member attribute declaration, it can still be modified in the constant function
The object data pointed to by this pointer can be modified

void ShowPerson() const {
	//const Type* const pointer;
	//this = NULL; // The pointer pointing to Person* const this cannot be modified;
	//this->mA = 100; // However, the data of the object pointed to by this pointer can be modified

	//const modifies the member function, indicating that the data in the memory space pointed to by the pointer cannot be modified, except for mutable modified variables
	this->m_B = 100;
}

Constant object:

Add const before declaring an object to call it a constant object
Constant objects can only call constant functions

public:
	int m_A;
	mutable int m_B; //Modifiable variable

Friends

The purpose of a friend is to let a function or class access private members in another class
Just declare it before, function / class

friend class goodGay;
friend void goodGay(Building * building);

The keyword of friend is friend
Three implementations of friends

Global function as friend
Class as friend
Member function as friend

Operator overloading

Plus operator overload

Person operator+(const Person& p) {
	Person temp;
	temp.m_A = this->m_A + p.m_A;
	temp.m_B = this->m_B + p.m_B;
	return temp;
}

Person p3 = p2 + p1;  //Equivalent to P2 operaor+(p1)

//function overloading
Person operator+(const Person& p2, int val)  
{
	Person temp;
	temp.m_A = p2.m_A + val;
	temp.m_B = p2.m_B + val;
	return temp;
}

Person p4 = p3 + 10; //Equivalent to operator+(p3,10)

For expressions with built-in data types, the operator cannot be changed
Do not abuse operator overloading
Shift left operator overload
Overloading the shift left operator with friends can output user-defined data types

ostream& operator<<(ostream& out, Person& p) {
	out << "a:" << p.m_A << " b:" << p.m_B;
	return out;
}
Person p1(10, 20);
cout << p1 << "hello world" << endl; //Chain programming

Increment operator overload

Realize your own integer data by overloading the increment operator

//Front++
MyInteger& operator++() {
	//First++
	m_Num++;
	//Return again
	return *this;
}

//Post++
	MyInteger operator++(int) {
		//Return first
		MyInteger temp = *this; //Record the current value of itself, and then add 1 to the value of itself, but the previous value is returned. Return first and then + +;
		m_Num++;
		return temp;
	}

The pre increment returns a reference and the post increment returns a value

Assignment operator overload

The c + + compiler adds at least four functions to a class

Default constructor (no parameters, empty function body)
Default destructor (no parameters, empty function body)
The default copy constructor copies the values of attributes
The assignment operator operator =, copies the value of the attribute

If an attribute in the class points to the heap, the deep and shallow copy problem will also occur during assignment

Person& operator=(Person &p)
	{
		if (m_Age != NULL)
		{
			delete m_Age;
			m_Age = NULL;
		}
		//The code provided by the compiler is a shallow copy
		//m_Age = p.m_Age;

		//Provide deep copy to solve the problem of shallow copy
		m_Age = new int(*p.m_Age);

		//Return to itself
		return *this;
	}

Relational operator overloading

Overloaded relational operators allow two custom type objects to be compared

bool operator==(Person & p)
{
	if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
	{
		return true;
	}
	else
	{
		return false;
	}
}

bool operator!=(Person & p)
{
	if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
	{
		return false;
	}
	else
	{
		return true;
	}
}

Function call operator overloading

function call operator  () It can also be overloaded
 Because the method used after overloading is very similar to the call of a function, it is called an imitation function
 Imitation function has no fixed writing method and is very flexible
void operator()(string text)
{
	cout << text << endl;
}

//Anonymous object call  
	cout << "MyAdd()(100,100) = " << MyAdd()(100, 100) << endl;

Anonymous function calls can also be used without initialization

inherit

·Inheritance is one of the three characteristics of object-oriented. There is a special relationship between some classes
·When defining these classes, the members of the lower level have their own characteristics in addition to the commonalities of the upper level.
·At this time, we can consider using inheritance technology to reduce duplicate code

Basic syntax of inheritance

//Public page
class BasePage
{
public:
	void header()
	{
		cout << "Home page, open class, login, registration...(Common head)" << endl;
	}
};
//Java page
class Java : public BasePage
{
public:
	void content()
	{
		cout << "JAVA Subject video" << endl;
	}
};

Inherited advantages

You can reduce duplicate code

class A : public B;

Class A is called a subclass or derived class
Class B is called a parent or base class

Members in derived classes consist of two parts:

One class is inherited from the base class, and the other is a member added by itself.
Inherited from the base class shows its commonness, while the new members reflect its individuality.

Inheritance mode

When public inherits, the members of the public type in the parent class will be inherited into the public of the child class, and the protected members of the parent class will also be inherited into the protected of the child class

When protected inherits, both public and protected members of the parent class will be inherited into the protected of the child class

When private inherits, the public and protected members of the parent class will be inherited into the private of the child class

class Son3:private Base3
{
public:
	void func()
	{
		m_A; //Access to private rights
		m_B; //Access to private rights
		//m_C; // Inaccessible
	}
};
class GrandSon3 :public Son3
{
public:
	void func()
	{
		//Son3 is a private inheritance, so the properties of inherited son3 cannot be accessed in GrandSon3
		//m_A;
		//m_B;
		//m_C;
	}
};

Object model in inheritance

Which members inherited from the parent class belong to the subclass object
Private members are just hidden, but they will inherit
The private members in the parent class are also inherited by the child class, but can not be accessed after being hidden by the compiler

Construction and deconstruction order in inheritance

After a subclass inherits from the parent class, when a subclass object is created, the constructor of the parent class will also be called
What is the construction and deconstruction order of parent and child classes?
In inheritance, the constructor of the parent class is called first, and then the constructor of the child class is called. The deconstruction order is opposite to that of the construction

Inherit the handling of members with the same name

When a member with the same name appears in the subclass and parent class, how can you access the data with the same name in the subclass or parent class through the subclass object?
You can access the member with the same name in the subclass directly
To access a member with the same name as the parent class, you need to add a scope
When a subclass has a member function with the same name as the parent class, the subclass will hide all versions of the member function with the same name in the parent class
If you want to access a member function with the same name hidden in the parent class, you need to add the scope of the parent class

s.func();//Subclass
s.Base::func();//Parent class

Inherit static member handling with the same name

Static members and non static members have the same name and are handled in the same way

Multiple inheritance syntax
C + + allows a class to inherit multiple classes

Syntax: class subclass: inheritance method parent class 1, inheritance method parent class 2

Multiple inheritance may cause members with the same name in the parent class, which needs to be distinguished by scope. Therefore, multiple inheritance is not recommended in the actual development of C + +.

class Son : public Base2, public Base1 
{
public:
	Son()
	{
		m_C = 300;
		m_D = 400;
	}
public:
	int m_C;
	int m_D;
};

diamond inheritance

Two derived classes inherit the same base class

Another class inherits two derived classes at the same time

This inheritance is called diamond inheritance, or diamond inheritance

Grass Mud Horse inherited animal data in two copies (sheep and camels). In fact, we should be clear that we only need one copy of this data.

The main problem caused by diamond inheritance is that subclasses inherit two copies of the same data, resulting in waste of resources and meaninglessness

The problem of diamond inheritance can be solved by virtual inheritance

class Animal
{
public:
	int m_Age;
};

//After adding the virtual keyword before inheritance, it becomes virtual inheritance
//At this time, the public parent class Animal is called the virtual base class
class Sheep : virtual public Animal {};
class Tuo   : virtual public Animal {};
class SheepTuo : public Sheep, public Tuo {};

polymorphic

Polymorphism is one of the three characteristics of C + + object-oriented

Polymorphisms fall into two categories

Static polymorphism: Function overloading and operator overloading belong to static polymorphism and reuse function names
 Dynamic polymorphism: Derived classes and virtual functions implement runtime polymorphism

Difference between static polymorphism and dynamic polymorphism:

Static polymorphic function address early binding - The function address is determined at the compilation stage
 Dynamic polymorphic function address late binding - Determine the function address at run time
class Animal
{
public:
	//The Speak function is an imaginary function
	//The virtual keyword is added in front of the function to become a virtual function, so the compiler cannot determine the function call when compiling.
	virtual void speak()
	{
		cout << "Animals are talking" << endl;
	}
};

If we want to pass in any object, we will call the function of any object

If the function address can be determined at the compilation stage, then static binding

If the function address can only be determined at the running stage, it is dynamic binding

void DoSpeak(Animal & animal)
{
	animal.speak();
}

The following conditions are met:

1. There is an inheritance relationship
2. Subclasses override virtual functions in the parent class

rewrite:

The function return value type is exactly the same as the function name parameter list, which is called rewriting

Polymorphic use:

A parent class pointer or reference points to a child class object

Advantages of polymorphism:

Clear code organization
Strong readability
It is conducive to early and later expansion and maintenance

//Polymorphic implementation
//Abstract calculator class
//Advantages of polymorphism: the code organization structure is clear and readable, which is conducive to early and later expansion and maintenance
class AbstractCalculator
{
public :

	virtual int getResult()
	{
		return 0;
	}

	int m_Num1;
	int m_Num2;
};

//Addition calculator
class AddCalculator :public AbstractCalculator
{
public:
	int getResult()
	{
		return m_Num1 + m_Num2;
	}
};

//Subtraction calculator
class SubCalculator :public AbstractCalculator
{
public:
	int getResult()
	{
		return m_Num1 - m_Num2;
	}
};

//Multiplication calculator
class MulCalculator :public AbstractCalculator
{
public:
	int getResult()
	{
		return m_Num1 * m_Num2;
	}
};


void test02()
{
	//Create addition calculator
	AbstractCalculator *abc = new AddCalculator;
	abc->m_Num1 = 10;
	abc->m_Num2 = 10;
	cout << abc->m_Num1 << " + " << abc->m_Num2 << " = " << abc->getResult() << endl;
	delete abc;  //When you run out, remember to destroy it

	//Create subtraction calculator
	abc = new SubCalculator;
	abc->m_Num1 = 10;
	abc->m_Num2 = 10;
	cout << abc->m_Num1 << " - " << abc->m_Num2 << " = " << abc->getResult() << endl;
	delete abc;  

	//Create multiplication calculator
	abc = new MulCalculator;
	abc->m_Num1 = 10;
	abc->m_Num2 = 10;
	cout << abc->m_Num1 << " * " << abc->m_Num2 << " = " << abc->getResult() << endl;
	delete abc;
}

int main() {

	//test01();

	test02();

	system("pause");

	return 0;

C + + development advocates the use of polymorphism to design program architecture
Because polymorphism has many advantages

Pure virtual functions and abstract classes
In polymorphism, the implementation of virtual functions in the parent class is usually meaningless

It is mainly the content overridden by calling subclasses

Therefore, virtual functions can be changed to pure virtual functions

Pure virtual function syntax:

virtual return value type function name (parameter list) = 0

When there is only one pure virtual function in a class, this class is also called an abstract class

Abstract class features:

Unable to instantiate object
 Subclasses must override pure virtual functions in abstract classes, otherwise they also belong to abstract classes
base = new Base; // Error, abstract class cannot instantiate object
base = new Son;

Virtual destruct and pure virtual destruct
When polymorphism is used, if an attribute in a subclass is opened to the heap, the parent class pointer cannot call the destructor code of the subclass when it is released

Solution:

Change the destructor in the parent class to virtual destructor or pure virtual destructor

Virtual destructor and pure virtual destructor have the following commonalities:

You can solve the problem of releasing subclass objects from parent class pointers
All need to have specific function implementation

Difference between virtual destruct and pure virtual destruct:

If it is a pure virtual destructor, this class belongs to an abstract class and cannot instantiate an object

Virtual destructor syntax:

virtual ~ class name () {}

Pure virtual destructor syntax:

virtual ~ class name () = 0;

Class name:: ~ class name () {} / / global definition

Generally, pointers are used to store such objects

void test01()
{
	Animal *animal = new Cat("Tom");
	animal->Speak();

	Releasing through the parent class pointer may lead to unclean cleaning of child class objects and memory leakage
	How? Add a virtual destructor to the base class
	The virtual destructor is used to solve the problem of releasing subclass objects through the parent class pointer
	delete animal;
}

1. Virtual destruct or pure virtual destruct is used to release subclass objects through parent class pointers

​ 2. If there is no heap data in the subclass, it can not be written as virtual destructor pure virtual destructor

​ 3. Classes with pure virtual destructors are also abstract classes

Keywords: C++

Added by jordanwb on Tue, 04 Jan 2022 11:03:30 +0200