Преобразование vtkSmartPointer в унаследованный класс - PullRequest
0 голосов
/ 18 сентября 2018

Как я могу привести vtkSmartPointer<T> к унаследованному классу, сохраняя подсчет ссылок?

Минимальная иллюстрация:

#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?     
}

Я предполагаю, что должен быть макрос где-то похожий на dynamic_pointer_cast<T> boost, но я не могу его найти. Если нет, и кто-то может предложить метод для достижения этой цели, я был бы очень благодарен.

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Здесь есть пара проблем.

  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 , глава "14.6 Написание класса VTK".

0 голосов
/ 18 сентября 2018

Хорошо, неважно, я нашел ответ, который, кажется, работает. Я опубликую это на случай, если кто-то споткнется и захочет избежать разочарования, которое у меня было.

Оказывается, что подсчет ссылок происходит в 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>();
}
...