将 vtkSmartPointer 转换为继承 Class
Casting vtkSmartPointer to an Inherited Class
如何在保持引用计数的同时将 vtkSmartPointer<T>
转换为继承的 class?
最小插图:
#include <iostream>
#include <vtkSmartPointer.h>
class A: public vtkObjectBase {
public :
A(){}
static A * New(){return new A();}
int var1 = 8;
};
class B: public A {
public :
B(){}
static B * New() {return new B();}
int var2 = 12;
};
int main (int argc, char ** argv) {
vtkSmartPointer<B> b = vtkSmartPointer<B>::New();
vtkSmartPointer<A> a = b; // this is fine
std::cout << "var1 = " << a->var1 << std::endl;
// this is not fine and I cannot find a vtk equivalent
// to boost's dynamic_pointer_cast for similar functionality
// vtkSmartPointer<B> c = a; // how do I do this?
}
我假设一定有一个类似于 boost dynamic_pointer_cast<T>
的宏,但我找不到它。如果没有,有人可以建议一种方法来实现这一点,我将不胜感激。
没关系,我找到了一个似乎有效的答案。我会 post 它以防有人偶然发现这里并想避免我遇到的挫败感。
事实证明,引用计数发生在 vtkObjectBase 中。所以只要代码继承自它,vtk 就会保持准确的计数。值得庆幸的是 vtk 不会让你使用 vtkSmartPointer 除非它允许。
因此,似乎要实现 boost 样式的宏,只需执行以下操作即可:
template<typename T,typename V> vtkSmartPointer<T> vtkDynamicPointerCast(vtkSmartPointer<V> src) {
T* v = dynamic_cast<T*>(src.Get());
if (v) return vtkSmartPointer<T>(v);
else return vtkSmartPointer<T>();
}
这里有几个问题。
- 在大多数情况下,您希望继承自
vtkObject
,而不是 vtkObjectBase
。
- 你错过了
vtkTypeMacro()
.
- 您要找的是
T::SafeDownCast()
。
因此您的代码将变为:
#include <vtkSmartPointer.h>
class A : public vtkObject {
public :
vtkTypeMacro(A, vtkObject);
A() = default;
static A* New() { return new A(); }
int var1 = 8;
};
class B : public A {
public:
vtkTypeMacro(B, A);
B() = default;
static B* New() { return new B(); }
int var2 = 12;
};
int main (int argc, char ** argv) {
vtkSmartPointer<B> b = vtkSmartPointer<B>::New();
vtkSmartPointer<A> a = b;
vtkSmartPointer<B> c = B::SafeDownCast(a);
}
有关更多信息,请参阅 VTK User Guide 章节“14.6 编写 VTK Class”。
如何在保持引用计数的同时将 vtkSmartPointer<T>
转换为继承的 class?
最小插图:
#include <iostream>
#include <vtkSmartPointer.h>
class A: public vtkObjectBase {
public :
A(){}
static A * New(){return new A();}
int var1 = 8;
};
class B: public A {
public :
B(){}
static B * New() {return new B();}
int var2 = 12;
};
int main (int argc, char ** argv) {
vtkSmartPointer<B> b = vtkSmartPointer<B>::New();
vtkSmartPointer<A> a = b; // this is fine
std::cout << "var1 = " << a->var1 << std::endl;
// this is not fine and I cannot find a vtk equivalent
// to boost's dynamic_pointer_cast for similar functionality
// vtkSmartPointer<B> c = a; // how do I do this?
}
我假设一定有一个类似于 boost dynamic_pointer_cast<T>
的宏,但我找不到它。如果没有,有人可以建议一种方法来实现这一点,我将不胜感激。
没关系,我找到了一个似乎有效的答案。我会 post 它以防有人偶然发现这里并想避免我遇到的挫败感。
事实证明,引用计数发生在 vtkObjectBase 中。所以只要代码继承自它,vtk 就会保持准确的计数。值得庆幸的是 vtk 不会让你使用 vtkSmartPointer 除非它允许。
因此,似乎要实现 boost 样式的宏,只需执行以下操作即可:
template<typename T,typename V> vtkSmartPointer<T> vtkDynamicPointerCast(vtkSmartPointer<V> src) {
T* v = dynamic_cast<T*>(src.Get());
if (v) return vtkSmartPointer<T>(v);
else return vtkSmartPointer<T>();
}
这里有几个问题。
- 在大多数情况下,您希望继承自
vtkObject
,而不是vtkObjectBase
。 - 你错过了
vtkTypeMacro()
. - 您要找的是
T::SafeDownCast()
。
因此您的代码将变为:
#include <vtkSmartPointer.h>
class A : public vtkObject {
public :
vtkTypeMacro(A, vtkObject);
A() = default;
static A* New() { return new A(); }
int var1 = 8;
};
class B : public A {
public:
vtkTypeMacro(B, A);
B() = default;
static B* New() { return new B(); }
int var2 = 12;
};
int main (int argc, char ** argv) {
vtkSmartPointer<B> b = vtkSmartPointer<B>::New();
vtkSmartPointer<A> a = b;
vtkSmartPointer<B> c = B::SafeDownCast(a);
}
有关更多信息,请参阅 VTK User Guide 章节“14.6 编写 VTK Class”。