Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

where downcasting is actually useful?

I know that downcasting is basically casting parent class pointer or reference to the derived class reference or pointer and for that you use dynamic_cast operator. But i can hardly think of any example. could y'all please explain?

like image 499
Bilal Sheikh Avatar asked Jul 07 '20 14:07

Bilal Sheikh


People also ask

What is the point of downcasting?

Downcasting is useful when the type of the value referenced by the Parent variable is known and often is used when passing a value as a parameter. In the below example, the method objectToString takes an Object parameter which is assumed to be of type String.

Why downcasting is not allowed?

Downcasting is not allowed without an explicit type cast. The reason for this restriction is that the is-a relationship is not, in most of the cases, symmetric. A derived class could add new data members, and the class member functions that used these data members wouldn't apply to the base class.

Is downcasting always safe?

So the downcast can't fail as long as you're sure b is of type Derived . Show activity on this post. That's a safe cast in the context. You've created Derived instance that's why it's always safe to treat Derived as Derived; no GC activity can spoil a part of the instance.

What is downcasting in Java and when it is required?

In Java, we rarely use Upcasting. We use it when we need to develop a code that deals with only the parent class. Downcasting is used when we need to develop a code that accesses behaviors of the child class.

What is the difference between upcasting and downcasting?

Downcasting is used when we need to develop a code that accesses behaviors of the child class. These are the following differences between Upcasting and Downcasting: 1. A child object is typecasted to a parent object. The reference of the parent class object is passed to the child class. 2. We can perform Upcasting implicitly or explicitly.

What is an example of a downcast in Java?

An example of a downcast might be if you cast from System.Object to some other type. Downcasting is unpopular, maybe a code smell: Object Oriented doctrine is to prefer, for example, defining and calling virtual or abstract methods instead of downcasting.

What is the use of downcasting in dynamic cast?

Here, it works since the variable `parent` is // holding an instance of Apple: Apple* child = dynamic_cast<Apple*>(parent); } Downcasting is useful when the type of the value referenced by the Parent variable is known and often is used when passing a value as a parameter.

Why do downcasts have to be manifest in the code?

That's why the downcasting operation is required to be manifest in the text of the program. It's so that you can more easily notice the smell and spend code review attention on it. in what circumstance [s] is it appropriate to write code which downcasts?


6 Answers

The curiously recurring template pattern (CRTP)

where downcasting is actually useful?

It is very useful when implementing the Curiously recurring template pattern:

template <class T> 
struct Base
{
    void interface()
    {
        // ...
        static_cast<T*>(this)->implementation();
        // ...
    }

    static void static_func()
    {
        // ...
        T::static_sub_func();
        // ...
    }
};

struct Derived : Base<Derived>
{
    void implementation();
    static void static_sub_func();
};

The common base class template interface provides definitions that delegates calls to the derived class implementations, realized (for non-static member functions) by downcasting the this pointer of the base class to a pointer type of the respective derived class (for the particular specialization of the base class template) followed by dispatch to a derived class function.

Note that that downcasting in this sense needn't necessarily be implemented in terms of dynamic casting; in this example a static cast is used to cast a base class pointer (this) to the respective derived class pointer.

like image 119
dfrib Avatar answered Oct 19 '22 05:10

dfrib


  1. You obtain abstract class from external/user code you do not trust too much. And you need to verify that it matches the type(s) you expect. If it doesn't match you report error instead of going UB. Furthermore, it would be a problem if you were to expose too much of your code/classes to users/external code - so you hide them behind interface classes.

  2. Useful for general object manager class - which stores abstract class without understanding what are those. So whenever user tries to obtain one of those and cast to appropriate type - it should apply dynamic cast to ensure that user didn't mess up with the types.

  3. It is needed for dealing complex classes with non-trivial hierachies - for which simple pointer cast will probably fail. Though, it is ill adviced to deal with such classes in general.

like image 22
ALX23z Avatar answered Oct 19 '22 06:10

ALX23z


The main situations where I've seen downcasting useful in object-oriented frameworks like .NET and Java are those in which all objects implementing a certain interface can be used perform some task a certain way, but some can also be used to perform the task in a faster way. For example, one might have an instance of some type which behaves as a collection that may be read by index, and want to copy a range of items from that type into an array of the item type. If the source object happens to be an instance of a known array-wrapper type that exposes the wrapped array (I think the C++ Vector<T> does that), down-casting to that type, accessing the array, and copying elements from it may be much faster than accessing each individual element through the wrapper.

In most such cases I've seen, the need for downcasting could have been avoided if the base interface had included more methods whose behavior was specified in a way that could be implemented by all types, even if not all implementations would be useful. For example, a "readable by index" collection could include a function that would return a structure containing either an array reference, an offset, and usable range of subscripts (if it wrapped an accessible backing array), or else a null array offset (if the backing array was inaccessible). At least in .NET and I think in Java (not sure about .NET), invoking a method of an interface an object is known to support is faster than testing whether an object supports an interface. I suspect the reason that Java and .NET didn't include such features in many of their widely used interfaces like Enumerable<T> (Java) or IEnumerable<T> (.NET) is that they didn't start out with any support for default interface methods, and thus including such methods would have massively increased the amount of bloat in common implementations.

like image 38
supercat Avatar answered Oct 19 '22 06:10

supercat


There are no common idioms / patterns that use dynamic downcasting because it is not very useful. The use of downcasting is indicative of a bad design.

If you find yourself in a rare situation where you think that you need dynamic downcasting because you've been painted into a corner by the design of a framework or a library, then know that dynamic cast is there for you. But most of the time (hopefully), you are not going to be in that situation.

If you cannot think of a case where you would need downcasting, then you are in a good place, and accompanied by most programmers.

For static down casting, see dfri's answer.

like image 26
eerorika Avatar answered Oct 19 '22 06:10

eerorika


Downcasting is widely used in Unreal Engine. There's even a dedicated Cast function that operates on integral representations of UObject-derived types which makes it cheap in terms of performance.

The engine comes with a base hierarchy of types that are supposed to be inherited and extended in your game module. The thing is these types hold base type pointers to themselves, so when you extend these types you will still use the variables defined by base engine types, unless you define your own - which won't give you the full support though.

Code like below is a common sight in Unreal Engine game code bases.

ACharacter* Character = GetCharacter(); // Base engine character type.
AMyCharacter* MyCharacter = Cast<AMyCharacter>(Character); // Extended game character type.

MyCharacter->Something();

This is not to say that it's a manifestation of good architecture but certainly a real life example of the practice.

like image 35
Vennor Avatar answered Oct 19 '22 04:10

Vennor


Often there are APIs or libraries which use callbacks to notify you of events. Those will usually have a tag that you pass that gets passed back to the callback function.

The problem with such a system is producing unique tags that can be associated back with a code object. The simplest system is to simply cast a pointer to the object to the tag type. That will fail spectacularly if a callback comes in after the object has been destroyed.

I have an alternative, a mixin class that keeps a table of tag numbers and object pointers. The constructor will generate a unique tag ID and place it in a table along with the pointer to the object. The destructor will remove it from the table. But since the pointer stored in the table is the mixin class and not the actual object, you need a cast to make it useful again.

template<typename T>
T* TagMixin::ObjectFromTag(Tag tag)
{
    TagMixin * p = TableLookup(tag);
    if (p == nullptr)  // (not found)
        return nullptr;
    return dynamic_cast<T*>(p);
}
like image 35
Mark Ransom Avatar answered Oct 19 '22 04:10

Mark Ransom