Reputation: 3280
I have 3 class which derived from each other:
class Basic{
...
}
class Extended : public Basic{
...
}
class Full : public Extended{
...
}
I have a template class which holds 5-5 from this classes:
template <class T>
class group{
public:
...
private:
T one, two, three, four, five;
};
group<Basic> basicGroup;
group<Extended> extendedGroup;
group<Full> fullGroup;
Can I easily cast for example fullGroup to basicGroup or extendedGroup to basicGroup? (I just want to cast upward)
Upvotes: 4
Views: 4679
Reputation: 31435
Most of the time you don't want to dynamic cast and don't care what type you have underneath. You have an operation you want to perform polymorphically on your base class and you just call it.
Note however though that your group template contains instances of the class, not pointers / shared-pointers to them. Thus you can't add a Full or Extended to a group of a lesser class without slicing it.
Upvotes: 0
Reputation: 76778
A solution would be to create a kind of view-class that can wrap a group, and exposes the individual objects as base-class instances:
template <class T>
class group{
public:
const T & getOne() { return one; }
private:
T one, two, three, four, five;
};
template <class T, U>
class group_view {
public:
group_view(group<T> & inner) : innerGroup(inner) {}
const U & getOne() { return dynamic_cast< const U &>(one); }
private:
group<T> & innerGroup;
};
You could use it like this:
group<Full> fullGroup;
group_view<Full, Extended> extendedGroupView(fullGroup);
If you extract the public interface of group
into an abstract base class, you can even use group_view
s polymorphically.
Upvotes: 3
Reputation: 53289
A class template with a different parameter is considered by the C++ type system to be an entirely different type. So, a group<Basic>
is not the same type as a group<Extended>
, and you cannot safely cast between these two types.
You can only cast upward on individual instances of Full
or Extended
.
Upvotes: 0
Reputation: 300
You cannot directly cast groups like this. What you need to do is either
Upvotes: 0
Reputation: 11028
No, these three types are unrelated, you cannot cast between them.
A good example to understand why is: imagine you have a std::list<Dog>
, where Dog
inherits from Animal
. You may thing it would be natural to consider that the std::list<Dog>
can be cast into a std::list<Animal>
; but what would happen with this code?
std::list<Dog> dogList;
// ... fill dogList as appropriate
std::list<Animal> animalList = dogList; // Should this be legal?
Animal aml = animalList.get(); // Fine; you get a Dog, which is an Animal
animalList.insert(Cat()); // Aww: you are trying to add a Cat to a Dog list!
Upvotes: 3
Reputation: 26060
You can't cast a container of one type to a container of another type. And in this case group is basically a container...
You need to copy one by one elements.
Upvotes: 0