Why does MATLAB give a "handle to deleted object" error when calling a property as a chain with the object's constructor in MATLAB R2021b?

5 ビュー (過去 30 日間)
I want to access a property of a class object. I'm trying to call a property as a chain with the object's constructor, and I get the error: "handle to deleted object". But when I splits the call into two parts by first calling the constructor, then calling the property, the code works as intended. I want to know why calling the property as a chain with the object's constructor does not work.

採用された回答

MathWorks Support Team
MathWorks Support Team 2022 年 10 月 27 日
The behavior you observed is expected. It is due to how references to handles work, coupled with the manner in which you have implemented the class destructor and how the class properties are being accessed.
Assume "MyClass1" and "MyClass2" are both handle classes. This means they can have multiple references to the same underlying object. An instance of a handle class is destroyed when there are no references to it, or when it is explicitly deleted. If a handle instance is explicitly deleted, all references to that instance will become handles to the deleted objects.
The "delete" method will look like the following in MyClass1:
function delete(obj)
    disp("MyClass1 Destructor");
    dbstack();
    delete(obj.prop2);
end
Assume the following line of code that tries to call the property as a chain with the object's constructor and stores the result in variable B:
>> B = MyClass1().prop2
This constructs a temporary instance of "MyClass1", and then immediately indexes into the result of that constructor call. Because this line of code creates a temporary instance of "MyClass1", MATLAB will delete that temporary instance once the line of code is done. This will invoke the class destructor. When the delete method is invoked, it will explicitly delete the value of "obj.prop2". That value is an instance of "MyClass2". The workspace variable B is a second handle to the same "MyClass2" instance stored in "prop2".  The fact that B holds a second reference to the same underlying object does not prevent the "delete(obj.prop2)" call from destroying that object. That's why B holds a handle to a deleted object.
The other two versions of the code behave differently. In the first case, the code would be like this:
A = MyClass1();
A.prop2
Here, there is no invocation of the "MyClass1"/"delete" method. The object is stored in the variable A, so remains in scope and is not destroyed, and the value of "prop2" will also not be destroyed.
In the second case, the implementation of the delete method is updated to remove the call to delete. In other words, it now would be like this:
function delete(obj)
    disp("MyClass1 Destructor");
    dbstack();
end
With this implementation, even if a temporary instance of "MyClass1" is created, there is no call to explicitly delete the contained "MyClass2" instance in "prop2". Therefore, the reference in workspace variable B to the "MyClass2" instance keeps it from being deleted.

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeHandle Classes についてさらに検索

製品


リリース

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by