C++ destructor and copy constructor

  1. Destructor (destructor)

-------------------------------------------------- -------------------------------------------------- --------

   1. Function
         When the address space of the object is released, the destructor will be automatically called.
         Function in actual development: destructor is often used to do finishing work, which is often done in QT.
              Example 1:
                     class YY
                     {                       public:                              YY()                              {                                  Open hardware device/file                              }                              ~YY()                              {                                  Close hardware device/file                              }








                     }
              Example 2:
                     class YY
                     {                       public:                              YY()                              {                                  p=new char[20]; //Allocate heap space                              }                              ~YY()                              {                                  delete []p; //Release heap space                              }                       private:                              char *p;                      }











   2. Grammar rules
         ~ class name ()
         {             source code of destructor;          }

   3. Characteristics of the destructor.
         First: The destructor has no return value type and no formal parameters.
         Second: The name of the destructor must be exactly the same as the class name.
         Third: If the programmer does not write a destructor, compilation The compiler will automatically generate a default destructor for you. Nothing is done in the source code of the destructor
                        ~ Cat()
                        {                         }          If the programmer writes the destructor, the compiler will not generate a default destructor for you. Function          No. 4: Destructor cannot be overloaded  
                           



================================================== ======================= Usage of destructor:

#include <iostream>
using namespace std;

class Cat
{
public:
	//定义一个构造函数
	Cat(int _age,float _weight);
	void show();
	
private:
	int age;
	float weight;
};

void Cat::show()
{
	cout<<"猫的年龄是: "<<age<<endl;
	cout<<"猫的体重是: "<<weight<<endl;
}

Cat::Cat(int _age,float _weight)
{
	cout<<"猫的构造函数调用了"<<endl;
	age=_age;
	weight=_weight;
}

int main()
{
	//创建猫的对象
	//Cat c1;  //对应的无参构造函数Cat()
	Cat c2(5,20.5); //对应的带参数的构造函数Cat(int,float)
	c2.show();

}

=========================================================================

2. Copy constructor

----------------------------------------------------------------------------------------------------------------

1. Function:
        When you initialize and assign an existing object to another new object, the copy constructor will be automatically called.  
        For example:
              int a=99;
              int b=a; //New variable b is defined. , and use a to initialize and assign the value to b
        for the same reason:
              Cat c1(5);
              Cat c2=c1; //Define a new object c2, and use c1 to initialize and assign the value to c2

   2. Grammar rules
        class name (class object reference)
        {               source code         }         Cat (Cat &other)         {         }




=================================================================

Example of copy constructor

#include <iostream>
using namespace std;

class Cat
{
public:
	Cat(int _age)
	{
		age=_age;
		cout<<"猫的带参构造函数"<<endl;
	}
	Cat()
	{
		cout<<"猫的无参构造函数"<<endl;
	}
	Cat(Cat &othercat)
	{
		cout<<"othercat地址是: "<<&othercat<<endl;
		cout<<"othercat里面的age值是: "<<othercat.age<<endl;
		cout<<"this is"<<this<<endl;
		cout<<"猫的拷贝构造函数"<<endl;
	}
	~Cat()
	{
		cout<<"猫的析构函数"<<endl;
	}
private:
	int age;
};

/*
	&在不同的场合表示不同意思
	类型名 &引用名;
	&变量名
	
*/
int main()
{
	//创造猫的对象
	Cat c1(5);
	cout<<"c1的地址是: "<<&c1<<endl;
	
	//写法一:调用拷贝构造函数
	Cat c2=c1;  //Cat(Cat &othercat)
	            //c2.Cat(c1);  //辅助你理解,但是这种写法本身是不正确的
				//Cat &othercat=c1;
				
	//写法二:调用带参构造
	//Cat c2(7);
	
	//写法三:调用无参构造
	//Cat c2;
	//c2=c1;
	
}

 ===================================================================

 3. Characteristics of the copy constructor
        : First: the name is the same as the class name, there is no return value type, there is only one formal parameter, and it is required to be a reference. Second: The
        programmer does not write a copy constructor, and the compiler will automatically generate a default one. copy constructor, but this default copy constructor has a bug
              : the default copy constructor, when it encounters the situation where the pointer allocates heap space, it will share the same heap space (no new heap will be reallocated) space),
              the situation where bugs occur is summarized into a formula:
                    class class name
                    {

                     private:
                        member variable 1;
                        member variable 2;
                        . . . . .
                        Type * pointer name; //If you have a pointer, you need to apply for heap space
                    }
                    Class name object 1;
                    Class name object 2 = object 1; //The bug occurs when the default copy constructor is called. Object 1 and object 2 share the same a heap space

    4. Deep copy and shallow copy.
         Shallow copy: The default copy constructor implements shallow copy.
         Deep copy: After programmers know the bug of shallow copy, they write the copy constructor by themselves. After solving the bug of shallow copy, we make our own The copy constructor written is called a deep copy

#include <iostream>
#include "myhead.h"
using namespace std;

class Cat
{
public:
	Cat(const char *_name,int _age)
	{
		//分配堆空间
		name=new char[20];//分配堆空间,并让成员chare *name指针指向该空间
		strcpy(name,_name);
		age=_age;
		cout<<"猫的带参构造函数,此时申请的name指向的堆空间首地址是: "<<(int *)name<<endl;
		cout<<"此时_name指向的对空间首地址是:  "<<(int *)_name<<endl;
	}
	~Cat()
	{
		delete []name;
		cout<<"猫的析构函数"<<endl;
	}
	
	//自定义拷贝构造函数--》实现深拷贝
	Cat(Cat &other)
	{
		//给当前对象的指针name单独申请堆空间
		this->name=new char[20];
		strcpy(this->name,other.name);
		this->age=other.age;
		cout<<"我自己写的是深拷贝"<<endl;
	}
	//修改猫的属性信息的函数
	void setattr(const char *newname,int newage)
	{
		strcpy(name,newname);
		age=newage;
	}
	void show()
	{
		cout<<"当前对象地址是: "<<this<<"  名字是:"<<name<<"  年龄是:"<<age<<endl;
		cout<<"name地址是:"<<(int *)name<<"    age的地址是:"<<&age<<endl;
	}
private:
	int age;
	char *name;
};

int main()
{
	//创造猫的对象
	Cat c1("小黄",5);
	Cat c2=c1; //一定会调用拷贝构造函数,我自己没有写拷贝构造,调用编译器自动生成的
	cout<<"c1地址是: "<<&c1<<endl;
	cout<<"c2地址是: "<<&c2<<endl;
	
	c1.show();
	c2.show();
	
	//我想修改c1的信息
	c1.setattr("旺财",6);
	cout<<"===========修改之后============="<<endl;
	c1.show();
	c2.show();
}

===============================================================

practise

1. You cannot use any C language library function. You can only use the methods in string to remove
               the characters that appear in string B (regardless of case) from string A.
                        For example: String A is " fhdshffFHDSHF"   
                               B string is "hfdhfd"    

#include <iostream>

using namespace std;

int main()
{
	int i,j;
	string A;
	string B;
	cout<<"请输入两个字符串!"<<endl;
	cin>>A;
	cin>>B;
	
	cout<<"A is: "<<A<<endl;
	cout<<"B is: "<<B<<endl;
	
	//伪代码分析理清思路--》代码中使用你喜欢的符号,汉字去分析思路
	for(i=0; i<B.length(); i++)
	{
		for(j=0; j<A.length(); j++)
		{
			if(B[i]==A[j] || B[i]-A[j]==32 || B[i]-A[j]==-32)
			{
				//删除A里面的这个字符
				A.erase(j,1);
				j--;  //很重要,防止漏掉一些字符,跟j++相互抵消
			}
		}
	}
	
	//打印删除之后的结果
	cout<<"=============删除之后=================="<<endl;
	cout<<"A is: "<<A<<endl;
	cout<<"B is: "<<B<<endl;
}

2. Define the button class class Button
         attribute:                the background color of the width
               and height buttons          requires defining different versions of the constructor to initialize different objects respectively.

#include <iostream>

using namespace std;

class Button
{
public:
	Button()
	{
		w=0;
		h=0;
		color=0;
		cout<<"无参构造函数"<<endl;
	}
	Button(int _w,int _h,int _color)
	{
		w=_w;
		h=_w;
		color=_color;
		cout<<"带参构造"<<endl;
	}
	
/* 
 	Button(int w,int h,int color)  //可读性太差
	{
		w=w;
		h=h;
		color=color;
	} */
	
private:
	int w;
	int h;
	int color;
};

int main()
{
	Button b;
	Button b1(100,50,0xffffff);
}

Guess you like

Origin blog.csdn.net/weixin_44651073/article/details/132702476