21 day good habit phase I-17

class

Class is used to implement function encapsulation

Class is used to describe "object". Class includes attributes and behavior. For example, the same person is a class. Attributes include people's character, character, appearance, etc. People's action performance belongs to class behavior (behavior is generally a function). A specific person is an instance of a class - an object.

A class is a template for an object, and an object is an instance of a class.

Class is a logical entity that encapsulates data and the code that operates on it

Class has three permissions:

Public permission: it can be accessed outside the class and within the class

Protected permission: it can not be accessed outside the class, but can be accessed inside the class, which is visible to derived classes

private permission: it cannot be accessed outside the class, but can be accessed inside the class

class Class name
{
    //Public access rights
    public:
    //Properties and behavior
    
    //Protect access
    protected:
    // Properties and behavior
    
    //Private access
    private:
    //Properties and behavior
};

The difference between class and struct is that the default permissions are different

If the attribute of a member is not declared in a class, it is private by default

In struct, the default is public

this pointer

The member function of the class can access the data of the class itself, so how to know which object's data is to be operated by the member function?

Access your address through the this pointer, which points to the object to which the called member function belongs

For example, student.show(); Then the student is the object and the this pointer points to it

this is a pointer to access a member variable or member function with - > instead.

Note: this pointer is not a part of the object. The memory occupied by this pointer will not be reflected in the sizeof operator.

This is actually a formal parameter of the member function. When calling the member function, the address of the object is passed to this as an argument. However, this parameter is implicit. It does not appear in the code, but is silently added to the parameter list by the compiler at the compilation stage.

1. The type of this pointer depends on the member function type using this pointer and the object type

2. this pointer can only be used in member functions, not global functions or static functions

The first parameter of the member function is T* const register this by default.

Returning * this means returning the object itself

3. This can only be used inside a class. Through this, you can access all members of the class, including private, protected and public attributes

const keyword

const function

cosnt modified member function: const member function can use all member variables in the class, but cannot modify their values. This measure is mainly set to protect data.

Constant member functions need to add const keyword at the end of the function header when declaring and defining

const object

Const can also be used to modify objects, called constant objects. Once an object is defined as a constant object, you can only call const members of the class (including const member variables and const member functions)

Static member

Static member variable

Static members should be declared inside the class and initialized outside the class.

Static member variables do not belong to any object. Static member variables are shared by all objects of the class

Only one static member variable is stored for all objects to share, so its value can be shared among all objects. Using static member variables to realize data sharing among multiple objects will not destroy the principle of hiding, ensure security and save memory.

class A {
public:
	static int a;//Static member variable declaration means adding static before the data type of the variable
};
int A::a = 0;

int main() {
	A temp0;
	temp0.a = 5;//Static member variables need to be defined, that is, allocate space for static member variables
	A temp1;
	cout << temp0.a << endl;
	cout << temp1.a << endl;
}
//The output of both lines is 5, indicating that the static member variables are shared

Static member variables can be modified in the const function

The cosnt function is used to protect all ordinary member variables of the object calling the const function (that is, the object pointed to by this pointer) so that they cannot be modified. However, static member variables do not belong to any object, so they can be modified.

class A {
public:
	static int a;
	int b;
	void changea(int i) const {
		this->a = i;//The this pointer accesses the static member variable a
	}
};
int A::a;
int main() {
	A temp0;
	temp0.changea(6);
}

Static member function

, a static member function also belongs to a class, and it does not belong to any object. Static member functions cannot access non static member variables in this class, because non static member functions can be called only after the class object is established. Therefore, in c + +, the main function of static member function is to access static member variables

class A {
public:
	static int a;
	int b;
    //Add static before the function to declare the function as a static member function
	static void showa(){
		cout << a << endl;
	}
	/*static void showb() {
		cout << b << endl;
	}*/
	//This annotated code will report an error
};
int A::a = 9;

int main() {
	A temp0;
	temp0.showa();
}

Friends

Friends provide a mechanism for ordinary functions or class member functions to access private or protected members in another class. That is, there are two forms of friends: friend functions and friend classes

Advantages: it improves the operation efficiency of the program.

Disadvantages: class encapsulation and data transparency are destroyed.

friend function

A normal function accesses private or protected members of a class. Declare in any region of the class and define outside the class

Format: friend type friend function name (parameter);

Friend class

Friend class < friend class name >;

  1. Unidirectionality: Class A declares that class B is its friend, and B can use the private member of a; However, a is not a friend of B and cannot use the private member of B.
  2. Friends cannot be inherited: Class A declares that class B is its friend, and a's son (inherited from a) and B are not friends.
  3. Friends are not transitive: Class A is a friend of B, class B is a friend of C, but C is not necessarily a friend of A.

For example, the following statement indicates that class B is a friend class of class A:*
class A
{
...
public:
friend class B;
...
};
After the above description, all member functions of class B are friend functions of class A and can access private and protected members of class A.

Object initialization and cleanup

Constructor

The main function is to initialize the member properties of the object when creating the object,

The initialization process of its object is controlled by one or several special member functions

Always used with the new operator

Syntax: class name () {}

1. Constructor, no return value, no void

2. The function name is the same as the class name

3. Constructors can have parameters and can be overloaded

4. When the program calls the object, it will automatically call the constructor without manual call, and it will only be called once

Classification and calling of constructors

1. Classification

Classification by parameters: parametric construction and nonparametric construction

Classification by type: common construction and copy construction

Copy constructors are commonly used to:

  • Initialize the newly created object by using another object of the same type.
  • Copy the object and pass the object as a parameter to the function to use all the properties of the object.
  • Copy the object and return it from the function.

Format: classname (const classname &obj){

/ / body of constructor

​ }

2. Call

(1) Bracket method

person p1;//Default constructor call (Note: do not use parentheses when calling the default constructor, because the compiler will recognize it as a declaration)
person p2(10);//Parameterized constructor call
person p3(p4);//Copy constructor call

(2) Display method

person p1 = person(10);//Constructor call with parameters. It is essentially an anonymous object. The anonymous object will be released after the current execution
person p2 = person(p1);//Copy constructor call. (do not initialize anonymous objects with copy constructors)

(3) Implicit construction

person p1 = 10;//Equivalent to person p1(10)
person p2 = p1;//Equivalent to person p2(p1)

Shallow copy and deep copy

Shallow copy: a simple assignment operation provided by the compiler

Deep copy: open up a new space in the heap for copying.

Differences between the two:

If only the attribute value of the object is copied, there is no difference between shallow copy and deep copy. The original object will be copied to produce a new object. Modifying the value in the new object will not affect the original object. The new object is completely separated from the original object.

If the elements in the copied object contain references (for example, if another list is stored in a list, the references in another list are stored), the shallow copy is different from the deep copy. Although the shallow copy copies the original object, it still saves the references. Therefore, modifying the values in the references in the new object will still change the values in the list in the original object, The new object is not completely separated from the original object. Unlike deep copy, it will create a new reference in the original object, that is, create a new list, and then put the reference of the new list, so that the new object can be completely separated from the original object

Therefore, shallow and deep copies are only for reference types

Destructor

The main function is that the system automatically calls and performs some cleaning work before the object is destroyed.

Syntax: ~ class name () {}

1. Destructor, no return value, no void

2. The function name is the same as the class name

3. Destructors cannot have arguments

4. The destructor will be called automatically before the object is destroyed. There is no need to call it manually, and it will only be called once

Operator overloading

Redefine the existing operator j and give it another function to adapt to different data types

Overload + operator

For example, there are two attributes m in a class_ A and m_B. When you create two members and add them

Class member function person operator + (person &p). One of the member attributes should be accessed by using the this pointer

Global function person operator + (person & P1, person & P2)

The difference between class member functions and global functions is that one is object-oriented and the other is process oriented

class person
{
public:
    int m_A;
    int m_B;
    person operator+(person &p)//Overloading through member functions+
    {
        person temp;
        temp.m_A = this->m_A + p.m_A;//Use the this pointer to access the properties of a1
        temp.m_B = this->m_B + p.m_B;
        return temp;
    }
};
//Overloading through global functions+
person operator+(person &p1, person &p2)
{
    person temp;
    temp.m_A = p1.m_A + p2.m_A;
    temp.m_B = p1.m_B + p2.m_B;
    return temp;
}
    person a1, a2;
    a1.m_A = 5;
    a2.m_A = 5;
    a1.m_B = 10;
    a2.m_B = 10;
    person a3 = a1 + a2;//Add two members

Overload < < operator

Function: direct output member function

Create global function ostream & operator < < (ostream & cout, person & P)

#include <iostream>
using namespace std;
class person
{
public:
    int a;
    int b;
};
//Using a reference is an alias. It will not open up new memory space and will not release the returned object
ostream &operator<<(ostream &cout, person &p)//The return type of cout is ostream
{
    cout << p.a << " " << p.b;//Chain thought
    return cout;
}
int main(void)
{
    person m;
    m.a = 10;
    m.b = 12;
    cout << m << endl;
    system("pause");
    return 0;
}

Overloading + + operators

Make members complete + + operations.

#include <iostream>
using namespace std;
class box
{
    friend ostream &operator<<(ostream &cout, box myprint); //Friends

public:
    box()
    {
        a = 0;
    }
    //Pre + +, increment first, and then return members
    box &operator++()
    {
        a++;
        return *this; //The purpose of returning a reference is to increment a data all the time
    }
    //Post + +, record first, then increment, and return the recorded value
    box operator++(int) //int is a placeholder parameter and a function overload occurs
    {
        box temp = *this;
        a++;
        return temp; //The local variable is released after the current function is executed. It cannot return a reference and needs to return a value
    }

private:
    int a;
};
//Overload < < operator
ostream &operator<<(ostream &cout, box myprint)
{
    cout << myprint.a;
    return cout;
}
//Post increment
void text01()
{
    box m;
    cout << m++ << endl;
    cout << m << endl;
}
//Pre increment
void text02()
{
    box m;
    cout << ++m << endl;
    cout << m << endl;
}
int main(void)
{
    text01();
    text02();
    system("pause");
    return 0;
}

Overload = operator

For classes with attributes pointing to the heap, there will be shallow copy and deep copy problems.

For shallow copies (error example)

//Shallow copy error example
//Purpose: copy m to n
#include <iostream>
using namespace std;

class box
{
public:
    box(int age)
    {
        A = new int(age);
    }
    ~box()//Destructor
    {
        if (A != NULL)
        {
            delete A;
            A = NULL;
        }
    }
    int *A; //The properties in the class are in the heap
};
void text01()
{
    box m(18);
    box n(20);
    n = m;
    cout << *m.A << " " << *n.A << endl;
}
int main(void)
{
    text01();
    system("pause");
    return 0;
}

An error will occur in this state because of the destructor. During the destructor, the heap area of n will be cleared first, and then the heap area of M will be cleared. Due to the shallow copy, members m and N share the same block of memory, which has been cleared twice, the program has an error.

**Solution: * * using the idea of deep copy, overload the assignment operator to open up another heap area for member n, so that the heap areas of the two members are independent of each other.

The implementation is as follows:

#include <iostream>
using namespace std;

class box
{
public:
    box(int age)
    {
        A = new int(age);
    }
    ~box()
    {
        if (A != NULL)
        {
            delete A;
            A = NULL;
        }
    }
    box &operator=(box &p)
    {
        //First judge whether there are attributes in the heap. If so, clear them first
        if (A != NULL)
        {
            delete A;
            A = NULL;
        }
        A = new int(*p.A);//Reopen a heap for n
        return *this;//Chain programming idea to realize continuous copy
    }
    int *A; //The properties in the class are in the heap
};
void text01()
{
    box m(18);
    box n(20);
    n = m;
    cout << *m.A << " " << *n.A << endl;
}
int main(void)
{
    text01();
    system("pause");
    return 0;
}

Overloading relational operators

#include <iostream>
#include <string>
using namespace std;

class person
{
public:
    person(string name, int age)
    {
        this->age = age;
        this->name = name;
    }
    //Overload = = operator
    bool operator==(person &p)
    {
        if (this->age == p.age)
            return true;
        else
            return false;
    }
    //Reload= operator
    bool operator!=(person &p)
    {
        if (this->age != p.age)
            return true;
        else
            return false;
    }
    string name;
    int age;
};
void test01()
{
    person p1("Tom", 18);
    person p2("Tom", 19);
    if (p1 == p2)
        cout << "same" << endl;
    if (p1 != p2)
        cout << "no" << endl;
}
int main(void)
{
    test01();
    system("pause");
    return 0;
}

Overload () operator (functor)

() is called a function call operator

Imitation function is flexible and has no specific writing method

#include <iostream>
#include <string>
using namespace std;
//A functor is not a function but a class
class person
{
public:
    //Copywriting output function
    void operator()(string s)
    {
        cout << s << endl;
    }
};
void test01()
{
    person myprint;
    myprint("hello world");
    person()("hello world");//Creates an anonymous function object when the specified object is not created
}
int main(void)
{
    test01();
    system("pause");
    return 0;
}

Posted on Mon, 08 Nov 2021 04:31:18 -0500 by covert215