Destructeur C++ et constructeur de copie

  1. Destructeur (destructeur)

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

   1. Fonction
         Lorsque l'espace d'adressage de l'objet est libéré, le destructeur sera automatiquement appelé.
         Fonction dans le développement actuel : le destructeur est souvent utilisé pour effectuer un travail de finition, ce qui est souvent effectué dans QT.
              Exemple 1 :
                     class YY
                     {                       public:                              YY()                              {                                  Ouvrir le périphérique/fichier matériel                              }                              ~YY()                              {                                  Fermer le périphérique/fichier matériel                              }








                     }
              Exemple 2 :
                     class YY
                     {                       public:                              YY()                              {                                  p=new char[20]; //Allouer de l'espace de tas                              }                              ~YY()                              {                                  delete []p; //Libérer de l'espace de tas                              }                       private:                              char *p;                      }











   2. Règles de grammaire
         ~ nom de classe ()
         {             code source du destructeur ;          }

   3. Caractéristiques du destructeur.
         Premièrement : le destructeur n'a pas de type de valeur de retour ni de paramètres formels.
         Deuxièmement : le nom du destructeur doit être exactement le même que le nom de la classe.
         Troisièmement : si le programmeur n'écrit pas de destructeur, compilez Le compilateur générera automatiquement un destructeur par défaut pour vous. Rien n'est fait dans le code source du destructeur
                        ~ Cat()
                        {                         }          Si le programmeur écrit le destructeur, le compilateur ne générera pas de destructeur par défaut pour vous. Fonction          n°4 : Le destructeur ne peut pas être surchargé  
                           



=================================================== ======================= Utilisation du destructeur :

#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. Copier le constructeur

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

1. Fonction :
        Lorsque vous initialisez et attribuez un objet existant à un autre nouvel objet, le constructeur de copie sera automatiquement appelé.  
        Par exemple :
              int a=99 ;
              int b=a; //Une nouvelle variable b est définie. , et utilisez a pour initialiser et attribuer la valeur à b
        pour la même raison :
              Cat c1(5);
              Cat c2=c1; //Définir un nouvel objet c2 et utiliser c1 pour initialiser et attribuer la valeur à c2

   2.
        Nom de la classe des règles de grammaire (référence de l'objet de classe)
        {               code source         }         Cat (Cat &other)         {         }




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

Exemple de constructeur de copie

#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. Caractéristiques du constructeur de copie
        : Premièrement : le nom est le même que le nom de la classe, il n'y a pas de type de valeur de retour, il n'y a qu'un seul paramètre formel et il doit être une référence. Deuxièmement : le programmeur n'écrit
        pas un constructeur de copie, et le compilateur générera automatiquement un constructeur de copie par défaut, mais ce constructeur de copie par défaut a un bug
              : le constructeur de copie par défaut, lorsqu'il rencontre la situation où le pointeur alloue de l'espace de tas, il partagera le même espace de tas (aucun nouveau tas ne sera réaffecté)),
              la situation où des bugs surviennent est résumée dans une formule :
                    class class name
                    {

                     privé :
                        variable membre 1 ;
                        variable membre 2 ;
                        . . . . .
                        Tapez * nom du pointeur ; //Si vous avez un pointeur, vous devez demander de l'espace de tas
                    }
                    Nom de classe objet 1 ;
                    Nom de classe objet 2 = objet 1 ; //Le bug se produit lorsque le constructeur de copie par défaut est appelé. Objet 1 et l'objet 2 partage le même espace de tas

    4. Copie profonde et copie superficielle.
         Copie superficielle : Le constructeur de copie par défaut implémente la copie superficielle.
         Copie profonde : Une fois que les programmeurs connaissent le bogue de la copie superficielle, ils écrivent eux-mêmes le constructeur de copie. Après avoir résolu le bogue de la copie superficielle, nous faisons notre own Le constructeur de copie écrit est appelé une copie profonde

#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();
}

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

pratique

1. Vous ne pouvez utiliser aucune fonction de la bibliothèque du langage C. Vous pouvez uniquement utiliser les méthodes de la chaîne pour supprimer
               les caractères qui apparaissent dans la chaîne B (quelle que soit la casse) de la chaîne A.
                        Par exemple : La chaîne A est " fhdshffFHDSHF"   
                               La chaîne B est " "    

#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. Définissez l'attribut Button class class Button
         :                la couleur de fond des boutons de largeur
               et de hauteur          nécessite de définir différentes versions du constructeur pour initialiser respectivement différents objets.

#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);
}

Je suppose que tu aimes

Origine blog.csdn.net/weixin_44651073/article/details/132702476
conseillé
Classement