Home > Blockchain >  Cast pointer of the base class to pointer of the inherited class with template
Cast pointer of the base class to pointer of the inherited class with template

Time:10-20

My code looks something like this:

class A {
    ...
};

template<typename T>
class B: public A {
    ...
};

A* pointerA = new B<X>(...);

But now I want to cast another pointerB to pointerA:

B<...>* pointerB = (B<...>*)pointerA;

How do I know what to insert into <...> or how I should do this correctly?

CodePudding user response:

You can try the cast with dynamic_cast. If you dynamic_cast to a pointer type and it fails, you get a null pointer back. If you dynamic_cast to a reference type and it fails, you'll get an exception.

Example:

#include <iostream>

class A {
public:
    virtual ~A() = default;
};

template<typename T>
class B : public A {};

int main() {
    A* pointerA = new B<int>;
    
    auto pointerB = dynamic_cast<B<double>*>(pointerA);
    if(pointerB) {
        std::cout << "cast succeeded\n";
    } else {
        std::cout << "cast failed\n";      // will print "cast failed"
    }

    delete pointerA;
}

If you have many of them stored in a vector you need to test all possible types to be able to cast back to the original type.

Example:

#include <iostream>
#include <memory>
#include <string>
#include <vector>

class A {
public:
    virtual ~A() = default;
};

template<typename T>
class B : public A {};

int main() {
    std::vector<std::unique_ptr<A>> vec;
    
    vec.emplace_back(new B<int>);
    vec.emplace_back(new B<std::string>);

    for(auto& ptr : vec) {
        if(auto b = dynamic_cast<B<int>*>(ptr.get())) {
            std::cout << "B<int>\n";
        } else if(auto b = dynamic_cast<B<std::string>*>(ptr.get())) {
            std::cout << "B<std::string>\n";
        } else {
            std::cout << "Oh, unknown derived type stored ...\n";
        }
    }    
}

It's preferable to add virtual methods to the base class and implement them in the derived classes to not have to do this cast at all though.

  •  Tags:  
  • c
  • Related