what would be a reason for upcasting in C++ in the code which will be used for numerical computations over huge amounts of data (a library that I’m using)?
Consider the following hierarchy:
template<class T>
class unallocatedArray
{
public:
unallocatedArray(int size, T t)
: size_(size), t_(0)
{
}
// Copy constructor. This is the only way to
// actually allocate data: if the array is
// passed as an argument to the copy constr.
// together with the size.
// Checks. Access operators. Iterators, etc.
// Wrappers for stl sorts...
private:
int size_;
T* t_;
};
template<class T>
class myArray
: public unallocatedArray<T>
{
public:
// This type actually allocates the memory.
myArray (int size)
: unallocatedArray<T>(size)
{
// Check if size < 0..
// Allocate.
this->t_ = new T[size];
}
myArray (int size, T t)
{
this->t_ = new T[size];
for (int i = 0; i < this->size_; i ++ )
{
this->t_[i] = t;
}
}
// Some additional stuff such as bound checking and error handling.
// Append another array (resizing and memory copies), equality
// operators, stream operators, etc...
};
template<class T>
class myField
: public myArray<T>
{
public:
// Constructors call the parent ones. No special attributes added.
// Maping operations, arithmetical operators, access operator.
};
//
template<class T>
class geomField
: public myField<T>
{
// myField but mapped on some kind of geometry, like surface meshes,
// volume meshes, etc.
};
This is just a very extremely simplified model, just to state that the access operator is defined all the way up, and the arithmetic operators are placed in the myField class. Now, what would be the reason for upcasting geomField to myField, if one needs to perform say 1e07 times the following:
access the element
perform arithmetical expression
in the following way:
GeomField<myType> geomFieldObject;
myField<myType>& downCast = geomFieldObject;
// Do the arithmetical operations on the downCast reference.
for two of such fields? Isn’t upcasting introducing some kind of penalty as well? Are the arithmetic operators not publicly available to the geomField: is this not the whole point of public inheritance?
I didn’t design this, it’s from an os library that I’m developing in. 🙂
Thanks!
I can only guess, but some of the arithmetical operations might have been overwritten in
geomFieldin order to implement the geometric mapping.If you have data in an
geomFieldbut want to perform unmapped operations, that might be a reason for upcasting.If, on the other hand, none of the operations that are executed on the casted reference are overwritten in
geomFieldthen you’re right that casting is not necessary.And generally, upcasting doesn’t introduce any performance drawbacks because usually (or even in every case, I’m not sure right now …) it is done completely at compilation time: Consider the following classes:
When you’re code looks like
it is translated by the compiler to something like
and
results in
i.e. there is no runtime overhead introduced by casting.