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.