其他分享
首页 > 其他分享> > 4 避免无用的缺省构造函数

4 避免无用的缺省构造函数

作者:互联网

缺省构造函数即没有参数或所有参数都声明了默认值的构造函数,可以在没有任何外部数据下初始化对象。当类没有声明构造函数,编译器会提供一个隐式缺省构造函数。

借由缺省构造函数创建的对象,其成员变量被初始化为固定的或是不确定的值,不能保证类的成员都被正确初始化。当类有一个无意义的缺省构造函数,未能将所有部分正确初始化,类的成员函数则必须另外测试成员变量是否是有效的,付出了更多的代码,因此应尽量避免。

没有缺省构造函数的类必须传入外部数据来构造,让人相信这个类的对象会被正确的实现,但也存在使用上的限制。

对象数组

直接声明对象数组,会调用类的缺省构造函数,如果没有则必须为数组初始化传参。

Class array[10];//error: no matching function for call to "Class::Class()"
Class array[10] = {{val1, val2, ...}, ...};//correct

但对于堆分配的对象数组(new []),并不能通过上述方式传参。

Class * array = new Class[2];//error: no matching function for call to "Class::Class()"
Class * array = new Class(value)[2];//error: 语法错误

可以通过(类)指针数组来替代对象数组,并逐个为指针分配堆内存。对应的,在释放时也需要逐个调用析构函数。

Class * array[10];
for(auto it : array)
{
    it = new Class(value);
}

指针数组的方式使用了额外的内存保存指针,可以使用placement new方法为数组分配raw memory,在内存中构造对象。

int size = 10;
void * memory = operator new[](size * sizeof(Class));//类似malloc返回未处理的堆内存块地址
Class * array = static_cast<Class *>(memory);
for(int i=0; i<size; ++i)
{
    new (&array[i]) Class(1, 2);//在已分配的地址上构造对象
}

释放时以相反的顺序首先逐个调用析构函数,最后释放内存。

for(int i=0; i<size; ++i)
{
    array[i].~Class();
}
memory = static_cast<void *>(array);
operator delete[] (memory);

在模板容器中使用

标准vector没有要求参数类型必须有缺省构造函数,但并不是所有容器都如此。没有缺省构造函数的类在模板中的兼容受到限制。

pair<int, Class> pa;//error: no matching function for call to 'std::pair<int, Class>::pair()'

虚基类

虚基类是否提供缺省构造函数是一个两难的决定。如果虚基类没有缺省构造函数,几乎所有的派生链在实例化时都必须给它的构造函数提供参数,那么无论派生多远都需要了解这些参数的意义才能正确初始化。如果虚基类提供缺省构造函数,就必须为安全性做保证,花费额外的代码去测试是否正确初始化。

标签:初始化,无用,缺省,new,array,Class,构造函数
来源: https://www.cnblogs.com/sandersunkown/p/15096447.html