Cannot access private member on adding to TArray

Hi,
The past few days i’ve been trying to get used to c++ in ue4 and I cant seem to find the reason for the following problem:
Im trying to add an element to a TArray, but I keep getting a compile error:

C2248    'UDFinedItem::UDFinedItem': cannot access private member declared in class 'UDFinedItem'	Gravity	D:\Program Files\Epic Games\UE_4.18\Engine\Source\Runtime\Core\Public\Containers\Array.h	1736 

`C2665	'UDFinedItem::operator new': none of the 2 overloads could convert all the argument types	Gravity	D:\Program Files\Epic Games\UE_4.18\Engine\Source\Runtime\Core\Public\Containers\Array.h	1736	

Im new to c++ so sorry if i am missing something stupid. And thanks in advance for any help
The code involved is:

DFinedItem.h:

#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "DFinedItem.generated.h"

/**
 * 
 */
UCLASS()
class GRAVITY_API UDFinedItem : public UObject
{
	GENERATED_BODY()
		static TArray<UDFinedItem> Items;
	protected:
		void registerItem(UDFinedItem & itm);
		FString name;
		FString displayName;
		int id;
		bool stackable;
	public:
		UDFinedItem();
		~UDFinedItem();
		virtual int getId();
		virtual FString getName();
		virtual FString getDisplayName();
};

DFinedItem.cpp:

    #include "DFinedItem.h"
    
    static TArray<UDFinedItem> Items;// Init(10, 5);
    UDFinedItem::UDFinedItem()
    {
    	registerItem(*this);
    }
    
    UDFinedItem::~UDFinedItem()
    {
    }
    
    int UDFinedItem::getId() {
    	return id;
    }
    
    FString UDFinedItem::getName() {
    	return name;
    }
    
    FString UDFinedItem::getDisplayName() {
    	return displayName;
    }
    
    void UDFinedItem::registerItem(UDFinedItem & itm) {
    	Items.Add(itm);
    }

The problem is that Items is not only private but also static. This means that all instances of UDFinedItem share the same Items array. As a result of this you need to access it in a different way in registerItem(). Your call

Items.Add(itm);

is the same as

this->Items.Add(itm);

What is not working as Items does not belong to this instance but to the class. So what you need is:

UDFinedItem::Items.Add(itm);

What I can not judge about from the code on the first view is if it makes sense to have a static array of items. If you need this, you probably want to save (shared/weak) pointers to UDFinedItems in it, not deep copies of the objects.

Thanks for the fast answer… However, changing to
UDFinedItem::Items.Add(itm);
still gives the same compile error…
As for doing this at all - not quite sure, as im trying to readapt from java, where this would definitely be the correct way, so i dont really know whats the bet way here

You only need the static keyword if you need the Array and its elements to persist across multiple class instances

Not sure exactly what the problem is but one thing is certain: you can’t declare an array of objects like that. They need to be object pointers.

Yes, thats what i intended

So would this be closer?

// Fill out your copyright notice in the Description page of Project Settings.
#include "DFinedItem.h"

static TArray<UDFinedItem*> Items;
UDFinedItem::UDFinedItem()
{
	registerItem(this);
}

UDFinedItem::~UDFinedItem()
{
}

int UDFinedItem::getId() {
	return id;
}

FString UDFinedItem::getName() {
	return name;
}

FString UDFinedItem::getDisplayName() {
	return displayName;
}

void UDFinedItem::registerItem(UDFinedItem* itm) {
	UDFinedItem::Items.Add(itm);
}

But that gives an even stranger error:

Error	LNK2001	unresolved external symbol "private: static class TArray<class UDFinedItem *,class FDefaultAllocator> UDFinedItem::Items" (?Items@UDFinedItem@@0V?$TArray@PEAVUDFinedItem@@VFDefaultAllocator@@@@A)	Gravity	D:\Unreal Projects\Gravity\Intermediate\ProjectFiles\DFinedItem.cpp.obj	1

No that’s better. You declared the Items array in the .h file but you didn’t define it in the .cpp file correctly.

It should be TArray<UDFinedItem*> UDFinedItem::Items;

My first answer wasn’t showing so I posted again, this time in more detail. Now that the original answer is back, I deleted the second one and I am copying the text from that in to this comment so the information isn’t lost. Here’s that answer:

There could be more than one issue but the first one I see is this: Items needs to be an array of pointers.

static TArray<UDFinedItem*> Items;

Also, the register function should take in a pointer to the object.

This is because UE4 expects UCLASS instances to be dynamically allocated. You can work with pointers and references. In this case, I think you want to use pointers.

Pointers are the biggest difference between C++ and C#/Java so it makes sense you’d bump into this. Keep an eye out for next time.

Oh, ok, yeah, thanks A LOT! It works now! I am very much grateful, it’s nice to get actual help on a forum, especially so quickly, so again, thanks a lot!