《More Effective C++》 4: 非必要不提供默认构造函数

在某个没有默认构造函数的类 class Object中,会在下面三种情况出现问题:

1、产生数组,由于在一般情况下,没有办法为数组提供构造函数的参数,因此,会出现各种问题。

#include <iostream>

using namespace std;

class Object
{
public:
	Object(int ID)
	{
		//... ...
	}
	//... ...
};

int main()
{
	Object objs[100]; //报错: 没有合适的默认构造函数可用
	Object* objs = new Object[100]; //报错: 没有合适的默认构造函数可用
	return 0;
}

《More Effective C++》提供了三种解决方案。

(1) 对于 non-heap 数组可以在定义数组时(heap数组不可用),改进:

Object objs[2] = {
		Object(0),
		Object(1)
	};
(2) 比(1)更一般的做法是使用指针数组代替对象数组:
Object* objs[10];
for (int i = 0; i < 10; i++)
{
	objs[i] = new Object(i);
}

这个方法有两个缺点:其一是容易出现资源泄漏问题,其二就是,消耗内存空间较大。

(3) 先为数组分配raw memory,然后使用“placement new”在这块内存上构造需要的对象。

	//分配足够的raw memory
	void* rawMemory = operator new[](10 * sizeof(Object));

	//让Object指针指向这段内存,这样就可以存储Object对象了
	Object* objs = static_cast<Object*> (rawMemory);

	//利用 placement new构造这块内存的Object对象
	for (int i = 0; i < 10; i++)
	{
		// 《More Effective C++》条款8有提到new的这种使用方式。
		new (&objs[i]) Object(i); 
	}
而对于上面那段空间的释放,也需要一定的技术的:
        //将Object对象按照与构造顺序相反的顺序析构。
	for (int i = 9; i >= 0; i--)
	{
		objs[i].~Object();
	}
	//释放 rawmemory
	operator delete[](rawMemory);


2、如果一个class没有默认构造函数,那么他将不适用于许多基于模板的容器类。

3.抽象基类如果缺乏默认 构造函数的话,其构造函数的参数将会来自遥远的子类,对于子类设计者来说,这是很恐怖的。


虽然没有默认构造函数会有以上的诸多不方便,但是,为了类的清晰度和效率,

《More Effective C++》建议,尽量不提供默认构造函数。

全部评论

相关推荐

投递大华股份等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务