将 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>();
}

这里有几个问题。

  1. 在大多数情况下,您希望继承自 vtkObject,而不是 vtkObjectBase
  2. 你错过了vtkTypeMacro().
  3. 您要找的是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”。