0

Suppose I have a UObject class with a TArray saved as UPROPERTY. Is there a way to create TArray dynamically and then set Objects to a newly created array (see code below)?

UCLASS(BlueprintType, Blueprintable)
class SOME_API UClassA : public UObject
{
    GENERATED_BODY()

public:    
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    TArray<UObject*> Objects;    
};

NewObject seems to raise a compilation error when trying to create TArray

UClassA* ObjA = NewObject<UclassA>();
TArray<UObject*>* NewArray = NewObject<TArray<UObject*>>(); // this raises compilation error
ObjA->Objects = *NewArray;

Error:

Error C2039 : 'StaticClass': is not a member of 'TArray<UObject *,FDefaultAllocator>'
Reference C2039 : see declaration of 'TArray<UObject *,FDefaultAllocator>'
Reference C2039 : see reference to function template instantiation 'T *NewObject<TArray<UObject *,FDefaultAllocator>>(UObject *)' being compiled
          with
          [
              T=TArray<UObject *,FDefaultAllocator>
          ]

Can I create TArray with simple c++ new will this work? Will the Garbage Collector keep track of new array instead of the Objects array created in the constructor?

Edit: I intend to create both TArray and contained UObjects dynamically. And I want the UE Garbage Collector to see them. This is meant the to be the only place they are stored.

2 Answers 2

0

NewObject<UClassA>() has already created a TArray<UObject*> with dynamic storage duration, as a member subobject of *ObjA. You don't need to new a second one.

The garbage collector does't deal with members, those are destructed by the destructor of the enclosing object.

If you want to fill a new TArray and then assign to ObjA->Objects, then you can use a local variable.

Sign up to request clarification or add additional context in comments.

7 Comments

This Objects array is meant to be the only place these UObjects are stored so that they won't be garbage collected. They will also be created dynamically. Also the intent was to create the TArray elsewhere in a factory. Is there a way to create an array dynamically and still have it referenced for UE GC system? I mean I need to mark the TArray with UPROPERTY. I maybe could have used pointer to the TArray in the body of UClassA but the objects it will contain will not be seen by GC would they?
I made an edit of the question in an attempt to clarify this
@Unicorn Why? It's preferable to have it be a data member. You already have marked Objects with UPROPERTY
Why what? And what do you mean preferable? You need to mark TArray as UPROPERTY so that it's containing objects will be counted for GC. I want new array created dynamically to be visible for GC also
@Unicorn At the moment, ~UClassA() destroys Objects. You don't need it to be garbage collected.
|
0

You may use Add or Emplace to add elements to the TArray if UClassA inherits from UObject (which should also have a virtual destructor):

TArray<UObject*> Objects;
//...
Objects.Add(new UClassA);

If you also want to create a single TArray dynamically, you could store it in a std::unique_ptr:

#include <memory>
//...
std::unique_ptr<TArray<UObject*>> Objects;
//...
Objects = std::make_unique<TArray<UObject*>>();

4 Comments

Sorry, the question is about dynamically creating TArray and another prerequisite is for the UObjects it stores to be seen by the garbage collector. I want to create both TArray and UObjects dynamically
@Unicorn Ok, I thought that was a mistake, but I clearly misunderstood that. I updated the answer.
I don't believe it is enough for GC system to see that this dynamic array holds references to UObjects. These objects may be deleted by GC because it does not see the dynamically created Array, no?
@Unicorn If I understand the UE documentation correctly you'll need to mark the UObjects ready for GC. So if you you could store unique_ptrs with a custome deleter to mark all of them automatically when the TArray is destroyed. I'm still not 100% sure why you'd want do allocate the ´TArray` dynamically though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.