Download

Help with inhertiance in C++

Hi all,

I’m relatively new to C++ (I’ve done a fair amount of Java beforehand) and I’m majorly struggling with inheritance. All I want to do is run the GenerateWordData() function in the code below in a different class but I can’t, for the life of me, get it to work.


#include "ThirdPersonCode.h"
#include "WordBank.h"
#include "Engine.h"

UWordBank::UWordBank(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
	WordArray.Add("Test");
	WordArray.Add("Spoons");
	WordArray.Add("Shoes");
	WordArray.Add("Potato");
	WordArray.Add("Green");
}

void UWordBank::GenerateWordData()
{
	RandWordNo = FMath::FRandRange(0, WordArray.Num());

	ActiveInputString = WordArray[RandWordNo];

	for (int i = 0; i < ActiveInputString.Len(); i++)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("%c"), ActiveInputString*));
	}

}

Any help would be greatly appreciated.

Regards,

acidrainlte

Where are you trying to call it from? Do you have an instance of your class created? Essentially, the only functional difference between Java and C++ here is that Java doesn’t have pointers. If you have a pointer to your instance, the way to call it would be:



myWordBank->GenerateWordData();


If you want to call it on an object rather than a pointer, then it’s just like Java



myWordBank.GenerateWordData();


If you want to call it from within your class, then you just call it the way you would a C function:




UWordBank::UWordBank(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
	GenerateWordData();
}


Make sense? Or did I misunderstand the question?

Its difficult to know what’s wrong without knowing the error. Reply back with the compiler output and we can better help you!

With that said, it sounds like your problem is that GenerateWordData is declared protected/private within UWordBank.h. This would make it only accessible from within UWordBank, which goes along with you not being able to call it from a different class. Make sure its a public function!

Thanks guys! I did set up the other class that I want to run the function in as a friend class but maybe I was doing that incorrectly.

I’ll take a look when I get home from work.

Hi guys,

So I tried this again today and I’m coming across the same issue. It compiles with no issues but when I try and play test it in UE, I get the below error:

GamePlay.png

Here is where I’m trying to run the code from (also includes other info):

The above code worked when I had the GenerateWordData method set up in the BeginPlay method.

Augh.

Your problem doesn’t have anything to do with C++ inheritance but rather the way UE4 works. You should not attempt to construct a UObject in the manner you currently are. FPostConstructInitializeProperties is a special concept unique to UE4 which contains a lot of information on how to construct your UObject. By simply passing a blank PCIP in this fashion, you are essentially bypassing all that information and creating an empty object. You must let the engine provide that PCIP by itself.*

It doesn’t seem like your WordBank needs to be a UObject to begin with. UObjects have a lot of extra functionality that makes the engine work. If all you need is a simple container, consider making a more lightweight class or struct:


struct FWordBank
{
    FWordBank();
    void GenerateWordData();
}

Keep the same implementation in your .cpp file, minus the PCIP structure. Then, simply include a FWordBank field within your game mode:


class AThirdPersonCodeGameMode : public AGameMode
{
    (...)
    FWordBank MyWordBank;
    (...)
}

Including the wordbank in this fashion will ensure it is initialized properly.

In the cases where you do need a UObject, you will have to use a different construction method. There are many different ones available, you can find a list here. In this case, the simplest notation will likely be enough – NewObject<UMyObjectType>().

*Note that in UE4.6, Epic is doing away with this requirement by providing a different way to access the information contained within the FPostConstructInitializeProperties structure. You will still need to use the aforementioned UObject constructors, however, unless you really know what you are doing.

Thanks! That’s it working now. When I thought about it earlier, I did think that the below was the case:

“By simply passing a blank PCIP in this fashion, you are essentially bypassing all that information and creating an empty object. You must let the engine provide that PCIP by itself.*”

I just wasn’t sure about how I could go about fixing it.

Sorry for asking such a silly question but thanks for taking the time to write out such a detailed answer! You’re right about it not needing to be a UObject so I’ve removed it. This is what I get for trying to do all my learning/coding during lunch at work!

Generally your would make something a UObject if you want to take advantage of Unreal’s Object handling system such as Garbage collection and reflection/replication etc. You are completely free to use standard c++ objects as well. But be aware that you’ll then be responsible for the object lifetime and memory management. In cmartels example above the object is contained in a struct that is a permanent member of the class so it’s lifetime is tied up to the scope of the GameMode so when the gamemode goes out of scope (ie gets cleaned up by the engine) it will also get cleaned up as well.

If you wanted dynamically created objects, then you could store a pointer to a c++ object and then call bog standard ‘new’ and delete yourself in the destructor but it’s up to you. And like cmartel said above, in 4.6 c++ is a little bit different. From now, all subobjects are stored as normal c++ pointers ( i would prefer unique or shared pointers, for memory safety but I guess the unreal object system has that taken care of under the hood).