Spawning Items from TArray in C++

I have an array of various effects which all inherit from a class - ProjectItemEffects
Inside it are then the actual different effects that I’m trying to spawn.

TArray<TSubclassOf<ProjectItemEffects>> ItemEffects;

It has one function inside which is just a simple:

virtual void DoStuff() override;

Now lets imagine inside the array described above it in actual live scenario there are 3 subclasses of ProjectItemEffects:

AProjIE_01 : public AProjectItemEffects
AProjIE_02 : public AProjectItemEffects
AProjIE_03 : public AProjectItemEffects

How would I go about spawning this items so that I can access the overloaded functions from those particular classes that are inherited from the base class?

If I was spawning the ‘base’ class I would do:

AProjectItemEffects* CurItemEffect = GetWorld()->SpawnActor<AProjectItemEffects>(AProjectItemEffects::StaticClass(), SpawnParams);

and then I would call:

CurItemEffect->DoStuff();

but the DoStuff() function does different things in each of the subclasses, so I need to get the reference of the class from the actual item in the array, have it spawn and have a reference to that particular spawned item with the correct TSubclassOf class cast.

I’m having issues with writing syntax correctly so it would compile, anyone who can provide some assistance, or do I have symantic / approach issue here?

I solved my problem by using:

for(i=0; i < ItemEffects.Num(); i++)
{
    ItemEffects[i].GetDefaultObject()->DoStuff();
}

which isn’t really an answer to my question but it did solve the issue. Still genuinly curious if its possible to do what I originally asked though for other purposes.

Extra information - this seems to work as I found it in another thread here:

But I still don’t know how I would dynamically create a class instance pointer to the return of the spawn function though so that it would ‘cast’ to correct class in the array.

for(i=0; i < ItemEffects.Num(); i++)
 {
     this->GetWorld()->SpawnActor(ItemEffects[i]);
 }

How would I go about spawning this
items so that I can access the
overloaded functions from those
particular classes that are inherited
from the base class?

You don’t need to once you have them in base class object pointers, thats the beauty of inference of virtual function. You can call DoStuff() without any casting on base class object and overridden class functions are called (not overloaded, overloaded is when you got same function with different arguments), not base class function.

Kind of strange you didn’t notice yet as basic events in engine require to override functions, if it does not work then it means you forgot “override” at the end of function deceleration, if you don’t do that you will hide function, which means you indeed will need pointer of object of that type in order to call that function, if won’t have it then you will be calling function of pointer type you have. Same goes if base function is not virtual, it needs virtual in order for override to work.

So do something like this (also i will show you nicer syntax for array looping which been added in C++11)

 TArray<AProjectItemEffects*> Effects
 Effects.Reserve(ItemEffects.Num()); //Preallocation for small speed up

//This way for loop automaticly handles grabing of each item and put them in "i", so you don't need to deal with index 
//Also TSubclassOf = UClass*, hmmmm maybe thats the real issue you have not knowing that ;]
for(UClass* i : ItemEffects) 
{
      Effects.Add(GetWorld()->SpawnActor<AProjectItemEffects>(i));
      //if you want call function on spawned object in this loop
      //grab it to local variable first and then put it in array

}

Effects[0]->DoStuff();

But if you ever want to cast to specific class, you can detect object class either by compireing UClass* from GetClass():

if(Effects[0]->GetClass() == AProjIE_01::StaicClass()) {

Or use IsA() function

if(Effects[0]->IsA(AProjIE_01::StaicClass())) {

or in more staic way:

if(Effects[0]->IsA<AProjIE_01>()) {

You can dynamiclly cast to specific class, so you need to figure what object you dealing with (thats why sometimes it good to make sub base classes if you have common functions in specific type of base class object, so you can cast more effectively)

Override was fine, the issue was the array was filled inside editor and when I spawned the item originally I spawned instance of base class rather than instance of the subclass which made the base class function execute rather than the one that should.

More than obviously I was way too tired and way too focused on the wrong problem last night when I wrote this.

Thanks for the extra explanation though, it is appreciated.