When should I do $cast with .clone() or not?

From the examples of UVM, I found the $cast used inside, some of them are $cast(rhs_, rhs.clone()) and others are not using clone() ($cast(rhs_, rhs)).

I don’t know when should I use clone() and when shouldn’t.

Can anyone tell me when should I use it or not?

Thanks.

The difference depends on whether you plan on writing to the object being cast or not.
In SystemVerilog, an assignment or cast of an class variable only copies the handle to the object, not the object itself. Most of the time, we create an object, assign or randomize values in that object, then pass the handle around. But sometimes we want to modify a local copy of the object, so we clone it (construct+copy=clone). If we didn’t clone the object, then everyone else who has the same andle to the object would see the modifications that we are making to it.

See optimization - What is copy-on-write? - Stack Overflow
More C++ Idioms/Copy-on-write - Wikibooks, open books for an open world

The clone method as defined below returns base class object type(i,e.uvm_object)

virtual function uvm_object clone ();

In your example above, if you use directly
rhs_ = rhs.clone();
The above fails as the return type for rhs.clone() is base class type(i,e uvm_object) and rhs_ is its derived type.
In System Verilog, you can never assign a parent class handle to a derived class handle.
However you can assign a parent to a derived type using $cast(casting is success only if the parent is previously pointing to the same derived object type).

Hence you have to call clone method using $cast.

In reply to malathi@aceic.com:

Hence you have to call clone method using $cast.

I think you have this reversed. A $cast is needed when using clone() with derived types, but clone() is optional when using $cast. The original question was when to use that option.

In reply to dave_59:

Good discussion here.
For me its is not too clear to understand as I am new to the object oriented language. I had seen this $cast and clone() at several driver codes. But it is really hard to understand the purpose
Could you please explain the (1)$cast, (2)clone() and (3)$cast+clone() with an simple lucid SV examples ?

Thanks and Regards,
karunani

In reply to dave_59:

Most of the time I see people just do the clone as a defensive strategy in uvm tb since they don’t know if there will be other parties that will write to it. Do you see the possibility of adding the optimization of copy on write by default for objects in uvm framework by overwriting the clone method for uvm_object or something like that? so that the user would still do clone regardless and the framework would only copy the object when somebody writes to it.