在使用STL容器时避免使用具有复杂拷贝构造函数的类
来源:互联网 发布:mac怎么映射键盘 编辑:程序博客网 时间:2024/05/17 06:23
在使用STL容器时避免使用具有复杂拷贝构造函数的类。在向STL容器插入一个对象时,容器类会调用插入类的拷贝构造函数,如果插入类的拷贝构造函数很复杂,则将直接影响效率。
那么何谓复杂呢?比如,进行大量内存的拷贝,大量耗时的运算,等等,其实质就是需要做很多工作,需使用很多资源!如下例子说明了,即使CTest类定义了从int类型变量构造的方法,但同样在STL容器中调用拷贝构造函数。
- #include <iostream>
- #include <deque>
- class CTest
- {
- //protected:
- int num;
- public:
- CTest(int i=0):num(i){std::cout<<"constructure CTest(int i=0)"<<std::endl;}
- CTest(const CTest & t):num(t.num){std::cout<<"constructure CTest(const CTest & t)"<<std::endl;}
- friend std::ostream & operator<<(const CTest & t,std::ostream & os);
- friend std::ostream & operator<<(std::ostream & os,const CTest & t);
- };
- std::ostream & operator<<(const CTest & t,std::ostream & os)
- {
- std::cout<<t.num;
- return os;
- }
- std::ostream & operator<<(std::ostream & os,const CTest & t)
- {
- std::cout<<t.num;
- return os;
- }
- int main(int argc, char * argv[])
- {
- std::deque<CTest> queue;
- for(int i=0;i<10;++i)
- {
- std::cout<<"push_front "<<i<<std::endl;
- queue.push_front(i);
- }
- for(std::deque<CTest>::const_iterator cit=queue.begin();cit!=queue.end();++cit)
- std::cout<<*cit<<std::endl;
- return 0;
- }
但并不意味着复杂或者说重量级的类不能使用STL容器来封装。我们可以将问题转化!在插入对象到容器中时,首先创建一个“空对象”,即默认构造函数,什么也不做,拷贝构造函数,也什么都不做,插入成功后,使用赋值的方式来完成对象的复杂拷贝构造函数需要做的事情!
上面的例子,只能用于说明在使用STL容器时的构造函数调用情况,不能说明为什么要将拷贝构造函数做成一个轻量级的函数。下面简单说明一下。
假设CTest内部有一个大块内存空间的属性。一般情况下,拷贝构造函数都会将右值对象中的内存复制到左值对象的内存。然而,一般情况下,这个类应该还会具有这样一个构造函数CTest(char * p);(假设这大块内存是一个很大的字符串几兆甚至几十兆)。那么在使用STL容器时,我们可能会这样做(假设使用前面的代码的queue):queue.push_front(buff);这样在CTest(char *p)的构造函数会复制着一大块内存,再调用拷贝构造函数时,又会复制这块内存一次,这样会影响程序的性能,假设,需要插入很多这样的元素,那么程序肯定在性能上受到严重影响。
解决办法:设计CTest();构造函数,什么也不做,也许只初始化内部指针为NULL;设计拷贝构造函数按照正常的情况完成代码,只不过,对于空对象,她已经不再有那么多事情要做了,例如:要复制的对象其内部内存指针为NULL,完全不需要复制大块内存;设计赋值运算符,完成内存拷贝工作:CTest & operator=(char * p);这样就会避免大量操作在两次构造函书中执行。
使用一个默认构造函数,简化STL内部类的拷贝构造函数工作,插入到STL容器后再修改类的状态执行更为复杂的操作,这样,避免了STL内部调用拷贝构造函数造成的可能影响性能的问题。
- 在使用STL容器时避免使用具有复杂拷贝构造函数的类
- 拷贝构造函数的参数为什么必须使用引用类型——避免拷贝死循环
- STL容器与拷贝构造函数
- STL容器与拷贝构造函数
- 拷贝构造函数的使用
- 具有拷贝构造函数的类作形参
- STL容器的构造函数
- STL容器与默认拷贝构造函数,默认赋值函数
- 拷贝构造函数使用const的原因
- 拷贝构造函数的使用时机
- C++构造函数和拷贝构造函数等的使用
- STL容器使用中的拷贝成本
- 拷贝构造函数 使用场合
- STL容器的使用
- 在C++拷贝构造函数中使用初始化列表
- STL容器的拷贝构造和赋值特性
- 关于在STL容器list中使用find_if 函数
- 正确的在遍历过程中使用STL容器的erase函数
- Effective J2ME
- 摆脱JavaScript中的绑定局面
- 学习Model-Glue框架的系列教程-Building your first Model-Glue Application中文理解通俗版(1)
- 浅析C++中虚函数的调用及对象的内部布局
- 女人嫁谁都后悔
- 在使用STL容器时避免使用具有复杂拷贝构造函数的类
- 深入JavaScript(apply和call函数)
- dreaweaver增加smarty自定义标签
- Java日期时间使用总结
- 其实只是一瞬间
- 业务驱动开发的关键原则
- VS2005编译错误:error PRJ0003 生成 cmd.exe 时出错
- 用枚举定义有意义的数组下标
- 把oracle表空间所对应的数据文件移动