C/C++ new 创建对象加不加括号的区别
(2015-09-30 01:44:04)
标签:
c/cnew |
分类: C/CPP |
比如,
int*p = new int;//p指向的int值是不确定的;
int*q = new int();//q指向的int值为0。”
ClassX a=new ClassX;
ClassX b=new ClassX();
有区别?
一、看到很多种说法:
http://bbs.csdn.net/topics/320161716
1.“加括号调用没有参数的构造函数,不加括号调用默认构造函数或唯一的构造函数,看需求”
明显不对,假设人为定义一个class,并只定义了一个带参数的构造函数(注意:一旦自定义了任何构造函数,默认构造函数(Default
Empty Constructor)将不复存在 ),那这个函数就是唯一的构造函数,那new
class()的时候就调用它了?
可是new
xx()的方式,参数值都没法传递。。。显然,不可能调用带参数的构造函数。
实际上,这种情况下, new
xx()根本通过不了编译,因为这种方式是调用无参构造函数来初始化一个类实例的,而这个类根本没有无参构造函数
然而,很多朋友都认为是这样的 (⊙﹏⊙)b……
2.“对于自定义类型(class/struct),调用的都是默认构造函数,没区别的。
只不过对于内建类型(int,
doube, char)不太一样,加了扩号会做默认值初值化,比如:int*
int*
当初比较赞这个观点,但是后来测了一下发现,也不完全是这样的!
-----------------------------------------------------------------------------------------------------
二、实践出真知:
XX *p1=new XX;
//输出"called Empty Constructor
"
cout<<p1->a:
不确定值
XX *p1=new XX;
//cout<<p1->a
//
不确定的值
int* p = new int;//printf结果 *p的值为不确定的整形;
int* q = new int();// *q的值是0!
double* p = new double;// *p的值不确定的浮点类型;
double* q = new double();// *q的值是0!
int* a1 = new int[10]; // 遍历结果: 元素值是不确定的;
int* a2 = new int[10](); // 遍历结果: 0,0,0,……0
//可见,加了括号,new确实可以在创建对象的同时把它初始化为0
(以前new int[N]以后,还傻傻的
memset来初始化,看来不用了!)
那么对于Class呢?
class XX{ public:
int a; XX(){ //显式声明一个无参构造函数(EmptyConstructor)
cout<<"called Empty Constructor "<<endl;
} };
XX*p2=new XX(); //输出"called Empty Constructor " cout<<p2->a: 也是不确定值!
//可见,加不加括号,都是调用了无参构造函数,但成员值都没有被初始化为0,
//似乎似乎观点2是正确的,即对于class,用new创建的时候,加不加括号都是一样的, 都没有初始化的作用,是这样吗?
去掉无参构造函数 的显式声明,再次测试,这时候将会调用默认构造函数:
class XX{
public:int a;
};
XX *p2=new XX(); //cout<<p2->a // 0!!! (看来也能初始化为0,观点2说的也不完全正确)
//看来 采用"new
classXX()"的方式创建class的对象,也具有初始化成员为0的作用 !
三、分析:
我们知道,在没有显式定义构造函数的时候,系统默认会设定default
Empty Construct,即默认无参构造函数,而一旦显式声明了任何其他构造函数,这个defaule Empty Construct
就不存在了。尤其是当我们定义了一个带参的构造函数以后,必须再显式定义一个无参构造函数,否则 XX xx;
或者 XX *p=new XX 或者 XX p=new
XX()都无法通过编译!说明这三种方式都是在调用无参构造函数。
上面两次尝试的差异在于:
第一次new xx(),是调用的用户自定义的无参构造函数;
第二次new xx(),是调用的系统的无参构造函数,也就是那个
default Empty Construct
所以,从结果可以看出,实现初始化为0是依靠的系统的默认无参构造函数(
default Empty Construct)!
前一个例子正是由于我们自定义了Empty构造函数,覆盖了系统的default Empty
Construct,同时自己定义的empty构造函数又没有实现初始化为0的操作,所以成员没有被初始化为0。
至于观点2,“对于内建类型(int,
doube, char)不太一样,加了扩号会做默认值初值化”
由于系统类型的“默认无参构造函数”不可能被用户改写,所以type xx=new
type()都是调用的default empty
constructor,所以一定具有初始化为0的效果!(观点正确)
“对于自定义类型(class/struct),调用的都是默认构造函数,没区别的。":
但是对于Class,classX *p=new classX() 和 classX *p =new
class效果确实都是一样的,但如果用户显示定义了构造函数,调用的就都是用户定义的那个Empty
Constructor,而不是默认构造函数。(观点错误)
四、总结:
type *p=new
type 不同于
type *p=new type()
前者只具有创建对象(变量)的作用,后者还具有初始化对象(变量)为0的作用!
*顺便提一句: classXX p;
和 classXX p();不一样,
前者是调用empty
constructor来创建对象,并且不具备初始化为0的作用,
而后者则是声明了一个名字为p、返回类型为classXX的函数!