C++ new 用法
来源:互联网 发布:软件合作开发合同范本 编辑:程序博客网 时间:2024/05/01 23:55
先看一下new和malloc的区别:
动态存储分配的运算符与函数的区别
malloc( )和free()是动态存储管理函数;
new 和delete是动态存储管理运算符。
它们功能类似但完全不同。
前者是函数,运行需要头文件,返回值无类型,创建对象时不调用构造函数(销毁对象时不调用析构函数);
而后者是运算符,不需要头文件,返回值有类型,创建对象时调用构造函数(销毁对象时调用析构函数)。
1.new 的三种使用方式
指针= new 类型名T 此时将调用无参构造函数;
指针= new 类型名T(初值列表) 此时将调用有参构造函数;
指针= new 类型名T [ size ] 此时将调用无参构造函数;
动态创建对象数组举例
- #include<iostream>
- using namespace std;
- class Point
- {
- public:
- Point()
- { X=Y=0; cout<<"Default Constructor called.\n";}
- Point(int xx,int yy)
- { X=xx; Y=yy; cout<< "Constructor called.\n"; }
- ~Point() { cout<<"Destructor called.\n"; }
- int GetX() {return X;}
- int GetY() {return Y;}
- void Move(int x,int y){ X=x; Y=y; }
- private:
- int X,Y;
- };
- void main()
- {
- Point *Ptr=new Point[2]; //创建对象数组
- Ptr[0].Move(5,10); //通过指针访问数组元素的成员
- Ptr[1].Move(15,20); //通过指针访问数组元素的成员
- cout<<"Deleting..."<<endl;
- delete[ ] Ptr; //删除整个对象数组
- }
动态数组类
- #include<iostream>
- using namespace std;
- class Point
- {
- public:
- Point()
- { X=Y=0; cout<<"Default Constructor called.\n";}
- Point(int xx,int yy)
- { X=xx; Y=yy; cout<< "Constructor called.\n"; }
- ~Point() { cout<<"Destructor called.\n"; }
- int GetX() {return X;}
- int GetY() {return Y;}
- void Move(int x,int y){ X=x; Y=y; }
- private:
- int X,Y;
- };
- class ArrayOfPoints //这个类叫“控制类”
- {
- public:
- ArrayOfPoints(int n) // 按照指示创建指定个数的对象
- {
- numberOfPoints = n;
- points = new Point[n];
- }
- ~ArrayOfPoints()
- {
- cout<<"Deleting..."<<endl;
- numberOfPoints=0;
- delete[] points;
- }
- Point& Element(int n)
- {
- return points[n];
- }
- private:
- Point *points; //类内只保存对象数组的首址
- int numberOfPoints; //对象的个数
- };
- void main()
- {
- int number;
- cout<<"Please enter the number of points:";
- cin>>number; //由用户指定对象个数
- //创建ArrayOfPoints对象points,该对象聚集了//Point类的对象数组
- ArrayOfPoints points(number);
- //通过指针访问数组元素的成员(两个层次)
- points.Element(0).Move(5,10);
- cout<<"points.Element(0): "<<points.Element(0).GetX()<<","<<points.Element(0).GetY()<<endl;
- //通过指针访问数组元素的成员
- points.Element(1).Move(15,20);
- cout<<"points.Element(1): "<<points.Element(1).GetX()<<","<<points.Element(1).GetY()<<endl;
- }
输出结果:
Please enter the number of points:2
Default Constructor called.
Default Constructor called.
points.Element(0): 5,10
points.Element(1): 15,20
Deleting...
Destructor called.
Destructor called.
Press any key to continue
动态创建多维数组
指针= new 类型名T[下标表达式1][下标表达式2]…;
如果内存申请成功,new运算返回一个指向新分配内存首地址的指针,是一个T类型的数组。
数组元素的个数为除最左边一维外各维下标表达式的乘积。
例如:char (*fp)[3]; fp= new char[2][3];
fp应是个指向多维数组的指针,指针的类型应是char [3],这是“大元素”类型,其中内嵌了一维数组。所以*fp一定要加括号,所以一定比对象数组少一维。
创建动态对象数组的又几种形式
Point a[2]={Point(1,2),Point(3,4)};
这叫“创建对象数组”,尽管无名,但不在堆区,在栈区。
Point b[2]={*new Point(1,2),*new Point(3,4)};
这叫“动态创建对象数组”,在堆区。
Point *Ptr=new Point[2];
这叫“动态创建无名对象数组”,在堆区。
Point *c[2]={new Point(1,2), new Point(3,4)};
这叫“动态创建对象指针数组”,在堆区。
new 的种类
plain new 普通new
void*operator new(std::size_t)throw(std::bad_alloc);
void operator delete( void *) throw();
nothrownew 不抛掷异常new
void*operator new(std::size_t,conststd::nothrow_t
& )throw();
void operator delete( void *) throw();
placement new 放置new
void*operator new(std::size_t,void );
void operator delete( void * ,void );
1. 普通new 的用法
该运算符在分配失败时将抛出异常,而非返回NULL。使用时要包含<new>头文件。
char *getMemory(unsignedlong size)
{
char * p = newchar[size];
return p;
}
void main(void)
{
try{
char * p = getMemory(1000000);//可能发生异常
// ...
delete [ ] p;
}
catch(conststd::bad_alloc& ex)
{ cout<<ex.what(); }
}
2.不抛掷异常new 的用法
该运算符在分配失败时不抛出异常,而是返回NULL。使用时要包含<new>头文件。
该函数的第2形参是structnothrow_t{ };类的全局常对象const nothrow_tnothrow; 用来作为new 运算符的标志.
void func(unsingedlong length)
{ unsingedchar * p = new(nothrow)
unsingedchar[length];
if ( p == NULL)
cout<<“alloctefailed !”;
// ...
delete [ ] p;
}
3.放置new 的用法
该运算符是在已分配的内存上重新构造对象,因为不分配内存,所以不必担心分配失败。唯一的工作是调用构造函数。要包含<new>头文件。
# include <new>
# include<iostream>
void main()
{
using namespace std;
char * p = new(nothrow) char [4]; //用nothrow
if (p == NULL)
{ cout<<“alloctefailed”<<endl; exit( -1 ); }
long * q = new(p)long(1000); //用placement
delete [ ]p; //只释放p,不要释放q.
}
p和q仅仅是首址相同,所构建的对象可以类型不同。所“放置”的空间应小于原空间,以防不测。
该运算符的作用是:只要第一次分配成功,不再担心分配失败。
# include <new>
# include<iostream>
void main()
{ using namespace std;
char * p = new(nothrow) char [100]; //用nothrow
if (p == NULL)
{ cout<<“alloctefailed”<<endl; exit( -1 ); }
// ...
long * q1 = new(p)long(100); //用placement
// ...
long * q2 = new(p) int[100/sizeof(int) ];
// ...
ADT * q3 = new(p) C[100/sizeof(ADT) ];
delete [ ]p; //释放.
}
注意:使用该运算符一定要显式调用析构函数,不可用delete代替析构,因为placement new 的对象的大小不再与原空间相同。
# include <new>
# include<iostream>
void main()
{ using namespace std;
char * p = new(nothrow) char [sizeof(ADT)+2];
if (p == NULL)
{ cout<<“alloctefailed”<<endl; exit( -1 ); }
// ...
ADT * q = new(p) ADT;
// ...
// delete q; // 错误
q-> ADT::~ADT();
delete [ ]p; //再释放内存.
}
- C++new的用法
- C++new的用法
- C++new的用法
- C++new的用法
- C++new的用法
- C++new的用法
- c++new的用法
- 【C++】new用法
- 【转载】C++new的用法
- 在C#new 的用法
- <C#>new几种用法
- 【转载】C++new的用法
- [C/C++] new的几种用法
- [C/C++] new的几种用法
- C ++ new的几种用法
- C++:new和delete的用法
- new用法
- .NET(c#)new关键字的三种用法
- spark 学习笔记
- BZOJ3343: 教主的魔法
- c++中this指针
- 多维分析OLAP引擎Mondrian学习
- Android Asynctask与Handler的比较,优缺点区别,Asynctask源码
- C++ new 用法
- spark sql读hbase
- 天兔(LEPUS)监控系统慢查询分析平台配置文档手册(V3.0)
- varchar int 后面长度说明
- 机器学习资源
- Java高级之1.5之后atomic包
- Android快速毛玻璃虚化效果实现
- FZU 1062 洗牌问题
- js跨域解决方案