本文最后更新于 115 天前,其中的信息可能已经有所发展或是发生改变。
1.前言
这两者的区别大家应该都知道,至于为什么我想写这一篇小记,主要是以前几乎不用vtkNew,最近想用一用,然后在不经意间出现了如下报错:
error: C2280: “vtkNew<vtkImageData>::vtkNew(const vtkNew<vtkImageData> &)”: 尝试引用已删除的函数
note: “vtkNew<vtkImageData>::vtkNew(const vtkNew<vtkImageData> &)”: 已隐式删除函数
后来发现是因为我把vtkNew声明的变量传给了参数为vtkSmartPointer修饰的参数,而vtkNew并不需要调用构造函数,其不能被拷贝,只能移动或通过指针传递,于是到现在才注意到这两者不能混用。
void func(vtkSmartPointer<vtkSomeClass> obj) {
/// ...
}
vtkNew<vtkSomeClass> newObj;
func(newObj); // 会报错
vtkSmartPointer<vtkSomeClass> smartPtrObj = newObj;
func(smartPtrObj); // 隐式转换后传递
2.详细介绍
2.1 使用格式
对于vtk,最初没有vtkSmartPointer和vtkNew,只能使用普通指针形式创建类对象,就需要手动释放:
vtkSomeClass *obj = new vtkSomeClass();
后来有了vtkSmartPointer智能指针,不需要手动释放。
更适用于需要多个对象或函数之间共享相同的 VTK 对象的场景,要注意的是,对象只有在最后一个 vtkSmartPointer 被销毁时才会被释放。
vtkSmartPointer<vtkSomeClass> obj = vtkSmartPointer<vtkSomeClass>::New();
再后来有了vtkNew智能指针,更为简便,不用调用构造函数去new,也不需要手动释放。
当超出作用域时,vtkNew 会自动调用析构函数释放资源。
vtkNew<vtkSomeClass> obj;
2.2 使用场景建议
考虑到两者的区别,更建议对需要变量共享的时候使用vtkSmartPointer,对不需要变量共享的时候使用vtkNew。比如对于全局变量或者需要利用函数传递变量时使用的时候使用vtkSmartPointer,对于只有局部作用域的变量使用vtkNew。注意不要犯像我那种的低级错误。