类和对象的初始化(构造函数与析构函数)

本文深入探讨了C++中的构造函数和析构函数,包括无参数、带参数、构造函数重载和类型转换。详细阐述了构造函数的用途,如初始化对象、设置默认参数和类型转换。同时,介绍了对象的生存期,包括局部对象、全局对象和动态创建对象的生命周期。此外,讲解了new运算符的三种用法及其在内存管理中的角色。
摘要由CSDN通过智能技术生成

有对象一定要有空间,有空间不一定有对象。

class Empty
{

};
int main()
{
	Empty e;
	cout << sizeof(e) << endl;//1字节
	return 0;
}

虽然此对象没任何属性和方法,但是要创建一个对象,就必须在地址空间标识此对象,就必须占有一个字节。

类的数据成员不能在类定义时初始化。

class student
{
    int num = 20060102;
    char name[15] = "张三";
    float score = 85;
};//错误

如果一个类中所有的数据成员都是公用的public,则可以在定义对象时对数据成员进行初始化。

class studet
{
    public:
    int num;
    char name[15];
    float score;
}stu1 = { 20010130101,"张三",85};

一、构造函数

数据成员多为私有的,要对它们进行初始化,必须用一个公有函数来进行。C++提供了构造函数来处理类对象的初始化问题。同时这个函数应该在且仅在定义对象时自动执行一次。称为构造函数(constructor) 。

构造函数就是用来在创建对象时初始化对象,为对象数据成员赋初始值。

构造函数用途:1)创建对象,2)初始化对象中的属性,3)类型转换。

构造函数是类的一种特殊的成员函数(在特殊用途中构造函数的访问限定可以定义成私有或保护)
,不需要人为调用;而是在建立对象时自动被执行。

特征:
1.C++规定构造函数的名字必须与类名相同。

2.构造函数无函数返回类型说明。注意是没有而不是void,即什么也不写,也不可写void。实际上构造函数有返回值返回的就是构造函数所创建的对象。

3.在程序运行时,当新的对象被建立,该对象所属的类构造函数自动被调用,在该对象生存期中也只调用这一次(由系统调用)

4.构造函数可以重载。严格地讲,类中可以定义多个构造函数,它们由不同的参数表区分,系统在自动调用时按一般函数重载的规则选一个执行。
5.构造函数可以在类中定义,也可以在类中声明,在类外定义。
6.如果类说明中
没有给出构造函数,则C++编译器自动给出一个缺省的构造函数.
            类名(void){     }

只要我们定义了一个构造函数,系统就不会自动生成缺省的构造函数。只要构造函数是无参或只要各参数均有缺省值的,C++编译器都认为是缺省的构造函数,并且缺省的构造函数只能有一个。默认构造函数——除了this指针以外没有参数的构造函数,函数体是空的,只能为对象开辟数据成员存储空间,而不能给对象中的数据成员赋初值。
构造函数定义形式:

类名(形式参数列表)

    {  函数体  }

1.1不带参数的构造函数

构造函数可以没有形参。

1>在类内定义构造函数:

#include<iostream>
using namespace std;
class student
{
public:
	student()
	{
		num = 20060102;
		strcpy(name,"张三");
		score = 85;
	}
	void display()
	{
		cout << "num:" << num << endl;
		cout << "name:" << name << endl;
		cout << "score:" << score << endl;
	}
private:
	int num;
	char name[15];
	float score;
};

2>在类外定义构造函数:

#include<iostream>
using namespace std;
class student
{
public:
	student();//类外定义构造函数
	void display()
	{
		cout << "num:" << num << endl;
		cout << "name:" << name << endl;
		cout << "score:" << score << endl;
	}
private:
	int num;
	char name[15];
	float score;
};
student::student()
{
	num = 20060102;
	strcpy_s(name, "张三");
	score = 85;
}

只要创建类的新对象,都要执行构造函数。定义对象自动调用构造函数

构造函数的主要用途就是:初始化类的数据成员。

用构造函数对对象进行初始化形式:

无参数的构造函数,定义对象的形式:

    类名  对象名1对象名2...... ;

有参数的构造函数,定义对象的形式:

       类名  对象名1(实参列表),对象名2(实参列表)...... ;

构造函数是一种成员函数,它具有一般成员函数的特点。

构造函数的名称与其类名相同

一个类中可定义一个或多个构造函数。

构造函数说明:

1) 构造函数是在创建对象时自动执行的,而且只执行一次,并先于其他成员函数执行。构造函数不需要人为调用,也不能被人为调用。

2) 构造函数一般声明为公有的(public),因为创建对象通常是在类的外部进行的。

3) 在构造函数的函数体中不仅可以对数据成员初始化,而且可以包含其他任意功能的语句,但是一般不提倡在构造函数中加入与初始化无关的内容。

带参数的构造函数对数据成员初始化,每一个对象的数据成员都得到同一组初值。

1.2带参数的构造函数

用带参数的构造函数对不同对象初始化

1>在类内定义构造函数

class  student 
          {  public:
                 student(int  n, string m, float s)
                     {  num = n;
                         name = m;
                         score = s;
                      } 
                 void display( )                             
                    {  cout<<”num: ”<< num<<endl;       
                        cout<<”name: ”<< name<<endl;   
                        cout<<”score: ”<< score <<endl;
                     }
              private:
                  int  num; 
                  string  name;    // 或char *name;
                  float  score;
         } ;

2>在类外定义构造函数

class  student 
          {  public:
                 student(int  n, string m, float s);
                 void display( )                             
                    {  cout<<”num: ”<< num<<endl;      
                        cout<<”name: ”<< name<<endl; 
                        cout<<”score: ”<< score <<endl;
                     }
              private:
                  int  num;
                  string  name;   // 或 char *name;
                  float  score;
           } ; 
       student::student(int  n, string m, float s )
          {  num = n;
              name = m;  
              score = s;
           } 

1.3在构造函数中用参数初始化表对数据成员初始化

构造函数可以使用参数初始化表对数据成员进行初始化,不在函数体内,而在函数首部实现。

一般形式为:

类名(形式参数列表):构造函数初始化

         {   函数体

          }

与其他的成员函数一样,构造函数可以定义在类的内部或外部,但初始化表的构造函数只在类体中定义中

class  student 
          {  public:
               student(int  n, string m, float s):num(n),name(m),score(s){ }               
                void display( )                             
                   {  cout<<”num: ”<< num<<endl;       
                       cout<<”name: ”<< name<<endl;   
                       cout<<”score: ”<< score <<endl;
                    }
              private:
                  int  num; 
                  string  name;    // 或char *name;
                  float  score;
         } ;

注意:如果数据成员是数组,就不能在参数初始化表对其进行初始化,应在函数体中用语句对其赋值。

初始化是在构建对象的时候赋值,赋值是在构建完成后才会赋值。

class  student 
          {  public:
              student(int  n, float s, char m[ ] ):num(n), score(s)//此处是初始化              
                 {  strcpy(name, m);//函数体中的叫赋值  } 
                 void display( )                             
                    {  cout<<”num: ”<< num<<endl;       
                        cout<<”name: ”<< name<<endl;   
                        cout<<”score: ”<< score <<endl;
                     }
              private:
                  int  num; 
                  char  name[15];    
                  float  score;
          } ;

初始化列表的顺序,并不是对象中成员初始化表的顺序,是按照类中属性声明的顺序构建

class  Complex
{
private:
	int Real;
	int Image;
public:
	Complex(int x) :Real{Image},Image{x}{}
	
	 void Print()
	 {
		 cout << Real << " " << Image << endl;
	 }
};
int main()
{
	Complex c1(10);

	c1.Print();

	return 0;
}

1.4构造函数重载

与一般的成员函数一样,在一个类中可以定义多个构造函数,即构造函数重载,只要每个构造函数的形参列表是唯一的。一个类的构造函数数量是没有限制的。

#include <iostream> 
using namespace std;
class  student 
    {  public:
           student( );
           student(int  n, string m, float s):num(n),name(m),score(s){ }                
       void display( ) ;                            
       private:
           int  num; 
           string  name;    
           float  score;
    } ; 
student::student( )
   {  num = 20060102;
      name = ”张三”;  
      score = 85;
   } 
void student::display( )                            
   {  cout<<”num: ”<< num<<endl;       
       cout<<”name: ”<< name<<endl;   
       cout<<”score: ”<< score <<endl;
   }
int main( )
   { student stu1;
      stu1.display( );
      student stu2( 20060103,“李四”, 88);
      stu2.display( );
      return 0;
   }
构造函数使用说明:

  1)在建立对象时不必给出实参的构造函数,称为默认构造函数。无参构造函数属于默认构造函数。一个类只能有一个默认构造函数。

  2)如果未定义构造函数,系统会自动提供一个默认构造函数,但它的函数体是空的,不起初始化作用。

  3)尽管在一个类中可以包含多个构造函数,但是对于一个对象来说, 建立对象时只执行其中一个,并非每个构造函数都被执行。 

1.5带默认参数的构造函数

在实际应用中,有些构造函数的参数值通常是不变的,只是在一些特殊情况下才需改变其值——可定义默认参数的构造函数

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

class  student
{
public:
	student(int  n = 20060101, string m = "张三", float s = 85);
	void display();
private:
	int  num;
	string  name;
	float  score;
};
student::student(int  n, string m, float s)
{
	num = n;
	name = m;
	score = s;
}
void student::display()
{
	cout << "num: " << num << endl;
	cout << "name:" << name << endl;
	cout << "score:" << score << endl;
}
int main()
{
	student stu1;
	stu1.display();
	student stu2(20060103,"李四");
	stu2.display();
	return 0;
}
构造函数默认参数的说明:

   1必须在类的内部指定构造函数的默认参数,不能在类外部指定默认参数。

class  student 
    {  public:
         student( int  n , string m , float s  );                
         void display( ) ;                            
         private:
            int  num; 
            string  name;    
            float  score;
     } ; 
student::student( int n=20060101, string m=”张三”, float s=85  )
     {  num = n;name = m;  score = s; }    //错误

2如果构造函数的全部参数都指定了默认值,则在定义对象时可以给一个或几个实参,也可以不给出实参。这时,就与无参数的构造函数有歧义了。

3在一个类中定义了带默认参数的构造函数后,不能再定义与之有冲突的重载构造函数。

一般地,不应同时使用构造函数的重载和带默认参数的构造函数

1.6用构造函数实现初始化方法总结

  1)在类中定义的构造函数的函数体中对数据进行赋初值。

  2)用带参数的构造函数,可以使同类的不同对象中的数据具有不同的初值。

  3)在构造函数中用参数初始化表对数据赋初值。

  4)在定义构造函数时可以使用默认参数。

  5构造函数可以重载,即在一个类中定义多个同名的构造函数。

        一般不应同时使用有默认参数的构造函数和构造函数的重载。

#include<iostream>
using namespace std;

class CGoods
{
private:
	enum{LEN=20};//枚举类型大小不计入结构体大小中
private:
	char Name[LEN];//直接将LEN替换为20
	int Amount;
	float Price;
	float Total;
public:
	CGoods(const char*name,int amount=0,float price=0.0):Amount(amount),Price(price),Total(amount*price)
	{
		strcpy_s(Name, name);
	}
	CGoods(){}

	void GoodsInfo()const
	{
		cout << " Name " << Name << " Amount: " << Amount << " Price " << Price << " Total_value: " << Total << endl;
	}
};
int main()
{
	CGoods ca;
	CGoods car("bya", 10, 12.00);
	CGoods book("c++", 10, 128.00);
	car.GoodsInfo();
	book.GoodsInfo();
	return 0;
}

1.7 对象的定义

下列定义的对象哪一个是错误的:

class  Complex
{
public:
	 Complex(){}
	 Complex(int r,int i):Real(r),Image(i){}
	 void Print()
	 {
		 cout << Real << " " << Image << endl;
	 }
	

private:
	int Real;
	int Image;
};
int main()
{
	Complex c1;
	Complex c2();
	Complex c3(12, 23);
	Complex c4 = Complex(1, 2);//直接将创建的对象给c4,没有借助中间对象,相当于Complex c4(1,2);
    c4 = Complex(3,4);//此种情况是创建一个无名对象,将无名对象的值给c4,因为c4此时存在,如果直接将构建的值给c4,那么c4就被构建了两次,这是不允许的
	Complex c5{};
	Complex c6{ 1,2 };
	c1.Print();

	return 0;
}

定义的c2不是对象

 c2系统认为是函数的声明,系统将 类型 名称 ()认为是函数的声明

如何想用()初始化对象,要么就要带默认值(eg:c3),不带默认值就不要写括号(c1)

1.8构造函数的用途——类型转换

class Int
{
private:
	int value;
public:
	Int(int x=0):value(x){}
	void Print()const { cout << value << endl; }
};
int main()
{
	Int a(10);//自己设计的类型
	a.Print();//10
	int x = 100;//系统内置类型
	a = x;//将int类型的x赋值给Int类型的对象a
	//隐式转换,用x的值构建一个临时对象,将这个临时对象赋值给a,赋值完成后,临时对象销毁,此临时对象称为将亡值
	a = (Int)x;//显式转换
	a.Print();//100
	
	return 0;
}

把一个变量给对象时,看起来像是把变量给对象赋值,实则不然。

把一个变量给对象,先调动对象的构造函数构建一个临时量,再把这个临时量赋值给对象。赋值完成后,临时量就会销毁,此临时量也称作将亡值。

关键字explicit

不允许隐式转化

构造函数要想可以类型转换,必须只有一个参数或者参数有默认值。

class Int
{
private:
	int value;
public:
	Int(int x,int y):value(x+y){}
	void Print()const { cout << value << endl; }
};
int main()
{
	Int a(10,20);
	a.Print();
	int x = 1, y = 2;
	a = x, y;//error
	a = (Int)(x, y);//强转也不行
	
	return 0;
}

构造函数有了默认值就可以了,就剩一个没默认值的参数

class Int
{
private:
	int value;
public:
	Int(int x,int y=0):value(x+y){}
	void Print()const { cout << value << endl; }
};
int main()
{
	Int a(10,20);
	a.Print();//30
	int x = 1, y = 2;
	a = x, y;
    //强转,只能是单参
	a = (Int)(x, y);//构造函数此时单参,只需要传一个参数,逗号表达式的值为最右边的值
	a.Print();//2
    //构建一个对象给a
    a = Int(x, y);
    a.Print();//3
    
	return 0;
}

二、析构函数

当对象脱离其作用域时(如对象所在的函数已调用完毕),系统会自动执行析构函数

析构函数也是一种特殊的成员函数,执行的是与构造函数相反的操作——通常用作执行一些清理任务(如释放对象所占用得内存等)。

析构函数定义形式:

~类名( )
    {

        函数体

    }

2.1析构函数的特点:

1.析构函数与构造函数的名字相同,但在其前面加上“~”。

2.析构函数没有任何参数,没有返回值也没有返回类型不能重载

3.一个类中只能有一个析构函数

4.对象销毁时,系统自动调用析构函数。

5.如果类说明中没有给出析构函数,则C++编译器自动给出一个缺省的析构函数。

eg:    ~类型名称(){}

class student 
{
public:
	student(int n, string m, float s)
	{
		num = n;
		name = m;
		score = s;
	}
	~student()
	{}
	void display()
	{
		
		cout << "num:" << num << endl;
		cout << "name:" << name << endl;
		cout << "score:" << score << endl;
	}
private:
	int num;
	string name;
	float score;
};
int main()
{
	student stu1(2020, "zhangsan", 80);
	stu1.display();
	student stu2(2021, "lisi", 90);
	stu2.display();
	return 0;
}

2.2析构函数说明:

1.每个类必须有一个析构函数,如果未定义析构函数,则系统自定义一个析构函数;
2.对于大多数类而言,不需要显式地编写析构函数,尤其是具有构造函数的类不一定需要定义自己的析构函数。析构函数通常用于释放在构造函数或在对象生命期内获取的资源(如动态分配的内存)。

2.3何时调用析构函数:

1)对象在程序运行超出其作用域时自动撤销,撤销时自动调用该对象的析构函数。如函数中的非静态局部对象。
2)如果用new运算动态地建立了一个对象,当用delete运算释放该对象时,调用该对象的析构函数。

2.4调用构造函数和析构函数的顺序

在使用构造函数和析构函数时,需要特别注意对它们的调用时间和调用次序。
构造函数和析构函数的调用很像一个栈的先进后出,调用析构函数的次序正好与调用构造函数的次序相反。最先被调用的构造函数,其对应的(同一对象中的)析构函数最后被调用,而最后被调用的构造函数,其对应的析构函数最先被调用。

先构造的后析构,后构造的先析构。

三、对象的生存期

3.1 局部对象

1>对于局部定义的对象,每当程序控制流到达该对象定义处时,调用构造函数。当程序控制走出该局部域时,则调用析构函数。


class  Complex
{
private:
	int Real;
	int Image;
public:
	Complex(int r=0,int i=0) :Real(r), Image(i)
	{
		cout << "Create Complex " << endl;
	}
	~Complex() {
		cout << "Destory Complex" << endl;
	}
	void Ptint()const
	{
		cout << "Real: " << Real << "Image: " << Image << endl;
	}


	void Print()
	{
		cout << Real << " " << Image << endl;
	}
};
void fun()
{
	Complex c1(1, 2);
	cout << "input block" << endl;
	{
		Complex c2(4, 5);
	}
	cout << "out block" << endl;
	return;
}

2>对于静态局部定义的对象,在程序控制首次到达该对象定义处时,调用构造函数。当整个程序结束时调用析构函数。

单纯的局部对象,tmp对象一直在构建析构构建析构,总共10次

class  Complex
{
private:
	int Real;
	int Image;
public:
	Complex(int r=0,int i=0) :Real(r), Image(i)
	{
		cout << "Create Complex " << endl;
	}
	~Complex() {
		cout << "Destory Complex" << endl;
	}
	void Ptint()const
	{
		cout << "Real: " << Real << "Image: " << Image << endl;
	}


	void Print()
	{
		cout << Real << " " << Image << endl;
	}
};
void fun()
{
	Complex tmp(1, 2);
}

int main()
{
	for (int i = 0; i < 10; ++i)
	{
		fun();
	}
	return 0;
}

当fun中的对象为静态局部对象时

void fun()
{
	static Complex tmp(1, 2);//静态对象,在数据区,有一个标记,运行时下次再遇到查看标记发小存在就不再构建
}

int main()
{
	for (int i = 0; i < 10; ++i)
	{
		fun();
	}
	return 0;
}

 

 在函数第一次调用时只构建一次,也析构一次。

3.2 全局对象

对全局定义的对象,当程序进入入口函数main之前对象就已经定义,这时要调用构造函数。整个程序结束时调用析构函数。

例:下列对象a,b,c,哪一个先构建

class Int
{
private:
	int value;
public:
	Int(int x = 0) :value(x) 
	{
		cout << "Create Int: " << value<<endl;
	}
	~Int()
	{
		cout << "Destory Int: " << value << endl;
	}
};
Int a(1);
int main()
{
	Int b(2);

	return 0;
}
Int c(3);

 

我们可以看到,a,c,b按照此顺序构建

 a和c是全局对象,b是主函数中的对象,在进入主函数之前,全局变量和全局对象就要构建出来,进入主函数之后,主函数中的对象才会被构建

3.3 动态创建的对象

动态创建的对象,使用new创建对象,delete释放对象.

malloc申请空间

1>下列程序可以运行成功吗?show可以被cp指针调用吗

class  Complex
{
private:
	int Real;
	int Image;
public:
	Complex(int r = 0, int i = 0) :Real(r), Image(i)
	{
		cout << "Create Complex " << endl;
	}
	~Complex() {
		cout << "Destory Complex" << endl;
	}
	void Print()const
	{
		cout << "Real: " << Real << "Image: " << Image << endl;
	}


	void show()
	{
		cout << "Complex::show " << endl;
	}
};
int main()
{
	Complex* cp = nullptr;
	cp->show();
	

	return 0;
}

//show(cp),传的是个空指针,this指针为nullptr,但是show方法中没有用到this指针所以可以调用show

class  Complex
{
private:
	int Real;
	int Image;
public:
	Complex(int r = 0, int i = 0) :Real(r), Image(i)
	{
		cout << "Create Complex " << endl;
	}
	~Complex() {
		cout << "Destory Complex" << endl;
	}
	//void Print( Complex *const this)const
	void Print()const
	{
		//cout << "Real: " << this->Real << "Image: " << this->Image << endl;
		cout << "Real: " << Real << "Image: " << Image << endl;
	}


	void show()
	{
		cout << "Complex::show " << endl;
	}
};
int main()
{
	Complex* cp = nullptr;
	cp->Print();
	//Print(cp),this指针为nullptr

	return 0;
}

2>那么cp可以调用print方法吗?

cp->print();

我们可以看到并不能调用成功。

Print方法中含有this指针,此时cp为nullptr,this指针为空,0地址不允许操作,

3>使用malloc申请空间的对象调用print方法可以成功吗

int main()
{
	Complex* cp = (Complex*)malloc(sizeof(Complex));
	if (cp == nullptr)return 1;
	cp->Print();


	return 0;
}

我们可以看到可以调用print方法,但是值为随机值。

 有空间但是没对象,

malloc给cp申请了4字节(X86)的空间,Print(cp);cp指向申请的空间,this指针也指向这个堆区空间,但是没有对象,所以值为随机值。

给cp构建一个对象:

int main()
{
	Complex c1(1, 2);
	Complex* cp = (Complex*)malloc(sizeof(Complex));
	if (cp == nullptr)return 1;
	cp->Print();
	*cp = c1;
	cp->Print();

	return 0;
}

 此时cp的值就不为随机值了

不允许拿对象给空间赋值,可以在空间中构建对象,但不允许用对象给空间赋值

如果拿对象给空间赋值,容易出问题,eg:virtual虚函数

virtual void Print()const
	{

		cout << "Real: " << Real << "Image: " << Image << endl;
	}

new申请空间 

class  Complex
{
private:
	int Real;
	int Image;
public:
	Complex(int r = 0, int i = 0) :Real(r), Image(i)
	{
		cout << "Create Complex " << endl;
	}
	~Complex() {
		cout << "Destory Complex" << endl;
	}
	virtual void Print()const
	{
		cout << "Real: " << Real << "Image: " << Image << endl;
	}


	void show()
	{
		cout << "Complex::show " << endl;
	}
};

int main()
{
	Complex* cp = new Complex(1, 2);//new 1.自动计算类型大小 2.调用malloc从堆区申请空间 3.调动构建函数构建对象 4.把对象地址给cp
	cp->Print();
	delete cp;//1.调用析构函数析构cp 2.将cp的堆空间还给系统,cp此时变成失效指针,main函数结束时,cp栈区空间才会释放
    cp = nullptr;
	return 0;
}

四、new三种用法:

4.1作为运算法(关键字)

p = new Pointer(10,20);//p是指针,Pointer 是类对象

new调用malloc在heap申请空间,调用Pointer类型在空间构建对象,返回。

4.2定位(构建)new

只要给定位new一个地址,就可以在此地址创建对象。

new(s) Pointer(12,23);//在s指向的空间调动构造函数,构建对象

delete p;//delete调动析构函数释放空间,再调用free销毁。

#include<iostream>
using namespace std;
class Object
{
private:
	int val;
public:
	Object(int x)
	{
		val = x;
		cout << "Create:" << val << endl;
	}

};

Object ObjA(1);
int main()
{
	Object Objb(2);
}
Object objc(3);

进入主函数之前就要为全局对象构建,再进入主函数编译从上到下,

int main()
{
	int a = 10;
	int b(10);//相当于调动了一个带参数的构造函数,拿10构建b
	/*伪构造函数*/
	int c = int(10);//类型名+(),调动其构造函数,构建c对象
	int* p = new int(20);//new申请int空间,调动int的构造函数构造整型
}

一个对象只能被构建一次,但可借助new实现二次构建,借助定位new可以对任何对象重新构建。

class  Complex
{
public:
	 Complex(){}
	 Complex(int r,int i):Real(r),Image(i){}
	 void Print()
	 {
		 cout << Real << " " << Image << endl;
	 }
	

private:
	int Real;
	int Image;
};
int main()
{
	Complex c1;
	Complex c2(12, 23);
    c1(23,34);//erro,对象只能构建一次
	new(&c1)Complex(23, 34);

	c1.Print();
	c2.Print();
	return 0;
}

4.3作为一个函数

 
int main()
{
	/* operator new,函数方法的使用,和malloc一样,需要sizeof计算空间大小,需要对返回值强转*/
	int* ip = new int(10);
	int* is = (int*)::operator new(sizeof(int));
	/*operator new 和 malloc 的不同*/
	//malloc申请空间空间不足会返回空指针
	//operator new 申请空间失败会抛出异常throw bad_alloc,所以使用new或operator new 判断是否申请成功不能用判空判断
 
	//可以使用nothrow,让new或者operator new申请空间失败不抛出异常,返回一个空指针
	int* ip = new(std::nothrow) int(10);
	int* is = (int*)::operator new(sizeof(int),std::nothrow);
 
	delete ip;//new 申请的空间用delete释放
	::operator delete(is);//operator new 申请的空间需要用::operator delete释放
 
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值