A detailed introduction to C++ classes and objects (1)

First, the concept and encapsulation of class

1. What is encapsulation

The first layer of meaning : Encapsulation is the most basic feature of object-oriented programming. Combine data (properties) and functions (methods) into a whole, which is implemented in the computer world with classes and objects. (encapsulate properties and methods)
The second layer of meaning : Encapsulate objective things into abstract classes, and classes can operate their own properties and methods only for trusted classes or objects, and hide information from untrusted ones. (Access control for properties and methods)

2. Class access control

  In C++, you can define access levels for attributes and methods of a class. Publicly modified attributes and methods can be accessed inside the class or outside the class. Privately modified properties and methods can only be accessed within the class.

3. The meaning of classes

A class encapsulates properties and methods, and at the same time controls access to the properties and methods of the class.
Classes are abstracted from objective things to form a class of things, and then use classes to define objects to form specific individuals of such things.
A class is a data type, a class is abstract, and an object is a concrete variable that occupies memory space.

4. Abstraction and encapsulation of circle classes

    #include<iostream>
    using namespace std;
/* 抽象一个圆类,并对圆的属性和方法进行封装 */
    class Circle
    {
        private:
    double r; /* 圆类的半径属性 */ 
    public:
    void setR(double r) /* 设置圆的半径 */
    {
        this->r = r;
    }
    double getR() /* 获取圆的半径 */
    {
        return this->r;
        }
    };

Second, the constructor

1 Introduction

  When we create an object, we often need to do some initialization operations, such as initializing properties. To solve this problem, C++ compilers provide constructors to handle object initialization. Constructor is a special member function that, unlike other member functions, does not require the user to call it, but is executed automatically when the object is created.

2. Definition and calling method of constructor

Definition: A special member function with the same name as the class can be defined in a C++ class. This member function with the same name as the class is called a constructor. A constructor can have a parameter list, but cannot have a function return value.
Call: In general, the C++ compiler will automatically call the constructor, but in some cases, you need to manually call the constructor.

3. Classification of constructors

No-Argument Constructor: A constructor has no function parameters.
Constructor with parameters: Constructors have function parameters.
Copy constructor: The parameter of the constructor is const ClassName &vriable.

4. Example and call of no-argument constructor

# include<iostream>
using namespace std;

/* 抽象一个圆类,并对圆的属性和方法进行封装 */
class Circle
{
private:
double r; /* 圆类的半径属性 */ 
public:
Circle() /* 无参构造函数 */
{
    cout << "无参构造函数被执行" << endl;
}
void setR(double r) /* 设置圆的半径 */
{
    this->r = r;
}
double getR() /* 获取圆的半径 */
{
    return this->r;
}
};

int main()
{
/* 无参构造函数的调用方式 */
Circle circle1,circle2;
} 

5. Examples of parameterized constructors and calls

# include<iostream>
using namespace std;

/* 抽象一个圆类,并对圆的属性和方法进行封装 */
class Circle
{
private:
double r; /* 圆类的半径属性 */ 
public:
Circle(int a,int b) /* 有参构造函数 */
{
    cout << "有参构造函数被调用" << endl;
}
void setR(double r) /* 设置圆的半径 */
{
    this->r = r;
}
double getR() /* 获取圆的半径 */
{
        return this->r;
    }
};

int main()
{
/* 有参构造函数调用方式一 */
Circle circle1(1, 2);
/* 有参构造函数调用方式二:程序员手工直接调用构造方法 */
Circle circle2 = Circle(1, 2);
}

6. Copy constructor example and call

1. How to call the copy constructor

The copy constructor is called when object1 is initialized with object2.
The copy function is called when object 1 is parenthesized to initialize object 2.
When an object (in this case an element rather than a pointer or reference) is used as a function parameter, the process of passing the actual parameter to the formal parameter calls the copy constructor.
When an object (here an element rather than a pointer or reference) is used as the function return value, if the same type is used to receive the return value, the copy constructor will be executed (this will involve the removal and retention of anonymous objects). problem, because the return object of the function is an anonymous object).
2. Example of calling the copy constructor

# include<iostream>
using namespace std;

class Location
{
private:
    int x;
    int y;
public:
    Location()
    {
        cout << "无参构造函数被执行" << endl;
    }
    Location(int x,int y)
    {
        this->x = x;
        this->y = y;
        cout << "有参构造函数被执行" << endl;
    }
    Location(const Location& location)
    {
        this->x = location.x;
        this->y = location.y;
        cout << "拷贝构造函数被执行" << endl;
    }
    ~Location()
    {
        cout << "x = " << this->x << ",y = " << this->y << "析构函数被执行" << endl;
    }

};

/* 模拟拷贝构造函数调用方式三 */
void setLocation(Location location)
{
    cout << "setLocation()全局函数..." << endl;
}

/* 模拟拷贝构造函数调用方式四 */
Location getLocation()
{
    cout << "getLocation()全局函数..." << endl;
    Location location(100, 200);
    return location;
}

/* 研究拷贝构造函数的调用 */
int main()
{
    /* 拷贝构造函数调用方式一 */
    cout << "###############方式一###############" << endl;
    Location loc1(1, 2);
    Location loc2 = loc1;

/* 拷贝构造函数调用方式二 */
cout << "###############方式二###############" << endl;
Location loc3(10, 20);
Location loc4(loc3);

/* 拷贝构造函数调用方式三 */
cout << "###############方式三###############" << endl;
Location loc5(5, 10);
setLocation(loc5);

/* 拷贝构造函数调用方式四 */
cout << "###############方式四###############" << endl;
/* getLocation()产生匿名对象赋值给loc6后,匿名对象执行析构函数,然后对象销毁 */
Location loc6;
loc6 = getLocation();
/* getLocation()产生匿名对象赋值给loc7,匿名对象被扶正,直接转成新对象 */
Location loc7 = getLocation();

}

7. Constructor Summary 

When no constructor is defined in the class, the C++ compiler defines a parameterless constructor for us by default, and the function body is empty.
When any constructor is defined in the class (including the copy constructor), the C++ compiler will not define the default constructor for us, which means that we must use the constructor if we define it.
By default, C++ provides a shallow copy of the copy constructor pointed to. Just a simple copy of the value of the member variable.
The copy constructor will not be provided to me by the C++ compiler until we write it. If not, the C++ compiler will always provide the default copy constructor.

Third, the destructor

1. Destructor definition and calling method

Definition: A special member function can be defined in a C++ class to clean up the object and release the memory we allocated in the object. This special method is called the destructor.
Calling: The destructor is automatically called by the C++ compiler when the object's lifetime is approaching the end.

2. The use of destructors

  Destruction is usually called before the end of the object's life cycle, and we will release the heap memory we created in the object at this time to ensure the rationality of the program.

# define _CRT_SECURE_NO_WARNINGS
# include<iostream>

using namespace std;

class Student
{
private:
    char * name;
    int age;
public:
    Student(char * name, int age)
    {
        /* 在构造函数中分配堆内存 */
        this->name = (char *)malloc(sizeof(name)+1);
        /* 初始化成员变量 */
        strcpy(this->name, name);
        this->age = age;
        cout << "构造函数被执行..." << endl;
    }
    ~Student()
    {
        if (this->name != NULL)
        {
            /* 在析构函数中释放堆内存 */
            free(this->name);
            this->name = NULL;
            this->age = 0;
        }
        cout << "析构函数被执行..." << endl;
    }
    void print()
    {
        cout << this->name << " = " << this->age << endl;
    }

};

int main()
{
    Student stu("王刚", 21);
    stu.print();
    return 0;
}

Fourth, the constructor and destructor of multiple objects

1. Object initialization list

  When we have a class member, which itself is a class, and this member has only one constructor with parameters and no default constructor, to initialize this class member at this time, we must call the parameterized constructor of this class member , at this time, the constructor can be used to initialize the object when defining the member, but if we want dynamic initialization, we need to dynamically accept the external data for the member, so the concept of object initialization list appears.

2. The members of the class are const modified

  When we have a class member, which is modified by const, it can be initialized directly when the variable is defined, or it can be initialized when using the object initialization list.

3. Object initialization example

# include<iostream>

using namespace std;

/* 定义A类 */
class A
{
private:
    int a;
    int b;
public:
    A(int a, int b)
    {
        this->a = a;
        this->b = b;
        cout << "A(" << this->a << "," << this->b << ")有参构造函数被执行" << endl;
    }
    ~A()
    {
        cout << "~A(" << this->a << ", " << this->b << ")析构函数被执行" << endl;
    }
};
/* 定义类B */
class B
{
private:
    A a1;
    A a2;
    const int n;
    const int m = 10;
public:
    /* 对象初始化列表:让成员变量从外界接收的方式来初始化 */
    B(int x,int y):a1(x,y),a2(10,20),n(100)
    {
        cout << "B(int x,int y)有参构造函数被执行" << endl;
    }
    ~B()
    {
        cout << "~B()析构函数被执行" << endl;
    }
};

int main()
{
    B b(1, 2);

    return 0;
}

4. Execution order of constructors and destructors

When there are objects in the class whose members are objects of other classes, the constructor of the member variables is called first, and the calling order is the same as the definition order of the member variables. After the constructors of the member variables are all executed, the constructors of the class are called.
The execution order of the destructor is "inverted", that is, the execution order of the constructor is reversed first.

Five, deep copy and shallow copy of copy constructor

1. Execution principle of copy constructor

  There are four ways to call the copy constructor. When we don't write the copy constructor, C++ writes the copy constructor for us by default, and the function body implements a simple copy of the value of the member variable. This default copy method, which we call shallow copy, simply copies the value of member variables to another object.

2. Throwing of the deep copy problem

  When our member variable is a dynamically allocated set of heap memory, at this time, the default copy constructor written by C++ for us copies the value of the member variable, then the copy will also point to the heap memory allocated by the original object, When we release the heap memory in the destructor, two destructors will occur (one is the original object to release the heap memory, and the other is the copy object to release the heap memory), thus causing the program to crash.

3. Deep copy code example

# define _CRT_SECURE_NO_WARNINGS
# include<iostream>
using namespace std;

class Student
{
private:
    char * name;
    int age;
public:
    /* 无参构造函数 */
    Student()
    {
        cout << "无参构造函数被执行..." << endl;
    }
    /* 有参构造函数 */
    Student(char * name, int age)
    {
        /* 在构造函数中分配堆内存 */
        this->name = (char *)malloc(sizeof(name) + 1);
        /* 初始化成员变量 */
        strcpy(this->name, name);
        this->age = age;
        cout << "有参构造函数被执行..." << endl;
    }
    /* 拷贝构造函数 */
    Student(const Student &student)
    {
        /* 重新分配内存 */
        this->name = (char *)malloc(sizeof(student.name) + 1);
        /* 初始化成员变量 */
        strcpy(this->name, name);
        this->age = age;
        cout << "拷贝构造函数被执行..." << endl;
    }
    /* 析构函数 */
    ~Student()
    {
        if (this->name != NULL)
        {
            free(this->name);
            this->name = NULL;
            this->age = 0;
        }
        cout << "析构函数被执行..." << endl;
    }
    void print()
    {
        cout << this->name << " = " << this->age << endl;
    }

};

int main()
{
    Student stu1("王刚", 22);
    /* 此时拷贝构造函数执行,在创建副本的时候进行深拷贝,则不会出现析构问题 */
    Student stu2 = stu1;

    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324756316&siteId=291194637