4. Classes in C++

1. Classes in C++

1. Three characteristics of the class:

  • Package:

    • 1. Encapsulate the functional function interface into the class
    • 2. Encapsulate data members into classes
  • inherit:

    • 1. The subclass inherits the function interface or data of the parent class, and there is no need to redevelop the interface to improve code reusability
  • Polymorphism:

    • The same operation acts on different objects and can have different interpretations to achieve different results. It improves code flexibility and maintainability.

2. Advantages of object-oriented programming

  • 1. The code is easy to modify and maintain (because each object is independent, you only need to modify the content of the object)
  • 2. Improve code reusability (inheritance, polymorphism, function overloading), and a lot less code
  • 3. Can better design complex programs

Second, the definition of a class in C++

class 类名
{
    
    
	//成员列表
}

This is the simplest way to define, but the class defined in this way is meaningless. Because the members of the class areprivate members, the outside world isInaccessibleof.

1. How to define a general class

class 类名
{
    
    
	public : //共有成员,外界可以访问
	
	protected : //保护成员,只有派生类可以访问
	
	private :  //私有成员,只有当前类内部可以访问
}

Example of defining a class:

class base
{
    
    
	public:
		int a; //外界可以访问,因为是共有成员
	protected:
		int b; //子类可以访问,因为是保护成员
	private:
		int c; //只有类的内部可以访问 ,因为是私有成员
};

Third, the constructor of the class in C++

1. Constructor:

  • 1. The function name is the same as the class name
  • 2. The function has no return value
  • 3. The function does not need to be called, it will be called automatically when the object is created

2. The role of the constructor:

  • Used to modify the data members in the object when creating the objectto initialize.

3. The syntax of the constructor:

class 类名
{
    
    
	public:
	类名() //构造函数
	{
    
    
	}
}

例子:
class base
{
    
    
	public:
	base()
	{
    
    
		cout << "调用构造函数" << endl;
	}
}

Notice:

  • Constructormust be written inpublic area, because the constructor is called automatically when the object is created. If it is not in the public area, it cannot be called, which will cause the creation of the object to fail
  • Assuming that the user does not write any constructor, the system will automatically generate a constructor with no parameters

hint:

  • 1. The constructor is alsoSupport function overloading
  • 2. The constructor is alsoSupport for default parameters

Exercise: Design a student class with common member name, protected member money, and private member id, and design a constructor to initialize these data members. And design an output interface.

#include <iostream>
using namespace std;

extern "C"
{
    
    
    #include <string.h>
}

class student
{
    
    
    public:
        student(const char *Name, int Money, int ID) : Money(Money), ID(ID)
        {
    
    
            strcpy(this->Name, Name);
        }
        void show()
        {
    
    
            cout << this->Name << this->Money << this->ID << endl;
        }

        char Name[32];
    protected:
        int Money;
    private:
        int ID;
};

int main()
{
    
    
    student stu("张三", 100, 180);
    stu.show();
}

Four, this pointer

effect:

  • used todistinguishInner and outer members
  • Whenever the user creates an object, this class will automatically generate a this pointer, pointing to the current classfirst address
base(int a,int b,int c)
{
    
    
	//this->a 当前类-》a 成员
	this->a=a;
	this->b=b;
	this->c=c;
}
//不使用 this 指针那么 a ,b ,c 变量的名字要重新修改!!

5. The difference between malloc and new

#include <iostream>
using namespace std;

extern "C"
{
    
    
    #include <stdlib.h>
}

class base 
{
    
    
	public:
		base(int a)
		{
    
    
			cout << "调用based的构造函数" <<endl;
			this->a = a;
		}
		
		void show()
		{
    
    
			cout << a << endl;
		}
		
	private:
		int a;
};

int main()
{
    
    
	//利用malloc分配base的空间
	base *p = (base *)malloc(sizeof(base));
	p->show();
	
	//利用new分配base空间
	base *q = new base(10086);
	q->show();
}

Notice:

  • Use malloc to open up space for classes,will not callThe constructor of the class will cause the members of the class to fail to initialize
  • Use new to open up the heap space of the class,can callConstructors to initialize members of a class

6. Destructor

  • 1. The function name is the same as the class name, add in front of the function name~
  • 2. The destructor has no return value.no parameters
  • 3. When the object is destroyed,automatic call. You can use the destructor to release the space of members in the class

effect:

  • Used to release data members initialized in the constructor

Notice:

  • The destructor cannot be overloaded, because the basis for overloading is the function parameter, and the destructor has no parameters
  • The destructor should also be written toPublic area, because it is called automatically when the object is destroyed

insert image description here

Seven, the size calculation in the class

Byte alignment principle:

insert image description here
Review the size calculation of the structure:

struct node
{
    
    
	char a;
	int b;
	short c;
	double d;
} //在64位的操作系统中计算该结构体的大小 -》24

Summarize:

  • The space size of the structure is based on the byte alignment principle, which is different in 32-bit and 64-bit systems. Please refer to the above table for specific alignment principles

The space size allocation in the class is the same as that of the structure

//当前类中 最大的字节是 int 所以按照4字节对齐原则
class base
{
    
    
	char a; //分配4个 char使用 1个剩下 3 个
	short b; //剩下的3个可以提供2个给 short去使用 所以剩下1 个
	int c; //重新分配 4 个空间
}; //->8
class base1
{
    
    
	char a; //分配4个
	int c; //分配4个
	short b; //分配4个
}; //根据 4 自己对齐原则 -》 12

in conclusion:

  • When designing data members of a class, the data type,To define in ascending order, the class defined in this way occupies the smallest memory space.

The size and member attribute relationship in the class:

insert image description here

Relationship between size and member functions in a class:

class base2
{
    
    
	public:
		void func() //在没有调用 func 的时候,b,c的空间是不会分配
		{
    
     
			//b 和 c 根本都不属于 base2类的空间中
			int b;//func 里面的局部变量 ,局部变量是临时存在的
			int c;
		}
		int a;
}; //4

in conclusion:

  • The size of the space in the class is only related to the data members in the class, and has nothing to do with the member functions in the class. (In addition to virtual functions

Hint: Empty classes have a size of 1

Eight, constructor parameter list initialization

effect:

  • A special initialization method in the constructor used to initialize the data members in the class
    insert image description here

hint:

  • This initialization method is not a panacea. If the data type does not support = assignment, this method cannot be used. Columns such as: array, string

Nine, copy constructor (key, difficult)

The shallow copy method automatically generated by the system:

#include <iostream>
using namespace std;

class base
{
    
    
	public:
		base(int a, int b, int c) : a(a), b(b), c(c){
    
    }
		void show()
		{
    
    
			cout << a << endl;
			cout << b << endl;
			cout << c << endl;
		}
	private:
		int a, b, c;
};

int main()
{
    
    
	base a(10, 20, 30);
	a.show();

	//通过一个对象去初始化另外一个人对象
	base b = a;
	//系统会自动生成一个浅拷贝构造函数,把a对象的数据赋值给b对象
	b.show();
}

insert image description here
Override the system's copy constructor:

  • When overriding the copy constructor, the parameters should be passed asquote, at this time, the default copy constructor of the system will be overridden. By rewriting the copy constructor, you can achievedeep copy

grammar:

class 类名
{
    
    
	public:
		类名(类名 &a) //重写后的拷贝构造函数 ,
		{
    
    
		}
}

hint:

  • When the user overrides the copy constructor, the system will not automatically generate a shallow copy method
    insert image description here
#include <iostream>
using namespace std;

class base
{
    
    
	public:
		base(int a, int b, int c) : a(a), b(b), c(c){
    
    }
		base (base &a)
		{
    
    
			cout << "调用拷贝构造函数" << endl;
			this->a = a.a;
			this->b = a.b;
			this->c = a.c;
		}

		void show()
		{
    
    
			cout << a << endl;
			cout << b << endl;
			cout << c << endl;
		}

	private:
		int a, b, c;
};

int main()
{
    
    
	base a(10, 20, 30);
	a.show();

	//通过一个对象去初始化另外一个人对象
	base b = a;
	//系统会自动生成一个浅拷贝构造函数,把a对象的数据赋值给b对象
	b.show();
}

ten,deep copy

Why do you need a deep copy? ?

  • Because the two objects are inshare a single address space. This is very dangerous.
    insert image description here

Rewrite the copy constructor to implement deep copy:

#include <iostream>
using namespace std;

extern "C"
{
    
    
	#include <string.h>
}

class base
{
    
    
	public:
		base (const char *str)
		{
    
    
			//分配p所指向的堆空间
			p = new char[1024];
			//把str数据赋值到堆空间中
			strcpy(p, str);
		}
		//重写拷贝构造函数,实现深拷贝!!!!!
		base (base &a)
		{
    
    
			cout << "调用重写后的拷贝构造函数,实现深拷贝"<< endl;
			//分配p所指向的堆空间
			p = new char[1024];
			strcpy(p, a.p);
		}

		void show()
		{
    
    
			cout << "堆空间的地址" << (void *)p <<"内容" << p << endl;
		}

		char *p;
};

int main()
{
    
    
	base a("hello");
	a.show();

	base b = a;
	b.show();
}

insert image description here
After using deep copy, the addresses of the heap space operated by the two objects are different.

11. Member functions in classes defined outside the class

grammar:

返回值 类名::函数名(参数列表)
{
    
    

}
-----------------------------------
例子:
class base
{
    
    
	public:
		void show(); //声明
};
//类外定义show 接口
void base::show()
{
    
    
	cout << "show base" << endl;
}

Exercise: Implementing Function Members Inside and Out

#include <iostream>
using namespace std;

extern "C"
{
    
    
	#include <string.h>
}

class base
{
    
    
	public:
		base(int size,const char *str);
		base(base &a); //深拷贝函数
		~base();
		void show();
	private:
		int size;
		char *p; //指向一块堆空间
};

base :: base(int size,const char *str)
{
    
    
	cout << "base 构造函数" << endl;
	this->size = size;
	p = new char[size];
	strcpy(p, str);
}

base :: base(base &a)
{
    
    
	cout << "base 深拷贝构造函数" << endl;
	p = new char[a.size];
	strcpy(p, a.p);
}

base :: ~base()
{
    
    
	cout << "base 析构函数" << endl;
	delete []p;
}

void base :: show()
{
    
    
	cout << p << endl;
}

int main()
{
    
    
	base a(1024, "Hello");
	a.show();

	base b = a;
	b.show();
}

Guess you like

Origin blog.csdn.net/qq_53402930/article/details/132402637