首页 > 代码库 > 关注C++细节——动态生成对象初始化细节

关注C++细节——动态生成对象初始化细节

①T *p =new T;

②T *p =new T();

这两类用法不同点的总结。

 

1.若T为类类型,且用户定义了构造函数,则两种形式的效果完全相同,都会调用这个定义了的构造函数来初始化内部成员变量,但是如果此构造函数中并未对成员变量初始化,则这个时候内部的成员变量进行默认初始化——值是未定义的。

2.若T为类类型,但是用户并没有定义任何构造函数,则我们可以知道编译器会为该类合成一个默认的构造函数,这个时候上述两种形式的结果就不同了,①的类内部的成员变量这个时候执行默认初始化,其值是未定义的。但是在②中就不同了,加了括号后,p内部的成员变量会执行值初始化,即以0的形式进行初始化(整数就为0,bool就为false,string 就为空)

3.若T为内置类型,则①的形式中*p的值为未定义的,②中进行值初始化如上。


下面针对上面各种情况进行编程测试。

1.显示定义构造函数,但构造函数并不对成员变量进行初始化,则无论①②都输出的a都是未定义的值。

class Test{
public:
	Test(){
		printf("constructor\n");
	}

	int getA()const{
		return a;
	}

private:
	int a;
};

int main(){
	Test *pta = new Test;
	Test *ptb = new Test();

	printf("a : %d\n", pta->getA());
	printf("a : %d\n", ptb->getA());
	return 0;
}


2.显示定义构造函数,并且构造函数中对成员变量就行初始化,则①②中a都是构造后的值。

class Test{
public:
	Test() : a(0){
		printf("constructor\n");
	}

	int getA()const{
		return a;
	}

private:
	int a;
};

int main(){
	Test *pta = new Test;
	Test *ptb = new Test();

	printf("a : %d\n", pta->getA());//output zero
	printf("a : %d\n", ptb->getA());//output zero
	return 0;
}
以上两个例子说明,只要定义了构造函数,无论new的时候加不加括号,都会调用自身已有的构造函数。

3.类中不定义任何构造函数,而使用编译器合成的默认构造函数。

class Test{
public:
	int getA()const{
		return a;
	}

private:
	int a;
};

int main(){
	Test *pta = new Test;
	Test *ptb = new Test();

	printf("a : %d\n", pta->getA());//undefined value       a->default initializer
	printf("a : %d\n", ptb->getA());//output zero			a->value initializer
	return 0;
}


4.内置类型的两种形式。

int main(){
	int *pia = new int;
	int *pib = new int();

	printf("%d\n", *pia);//undefined value
	printf("%d\n", *pib);//ouput zero
	return 0;
}