I have build a class in Unreal called Groundmode
GroundMode.h: #pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "Components/BoxComponent.h"
#include <NMR\GroundDirection.h>
#include "GroundMode.generated.h"
UCLASS()
class NMR_API UGroundMode : public UObject
{
GENERATED_BODY()
public:
UGroundMode();
};
GroundMode.cpp:
#include "GroundMode.h"
UGroundMode::UGroundMode() {}
I want to be able to instantiate this class in another class. PlayerPhysicsCollisionInfo.h
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "GroundMode.h"
#include "PlayerPhysicsCollisionInfo.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class NMR_API UPlayerPhysicsCollisionInfo : public UActorComponent
{
GENERATED_BODY()
public:
UPlayerPhysicsCollisionInfo();
UGroundMode downMode;
UGroundMode upMode;
UGroundMode leftMode;
UGroundMode rightMode;
};
PlayerPhysicsCollisionInfo.cpp: #include "PlayerPhysicsCollisionInfo.h"
void UPlayerPhysicsCollisionInfo::BeginPlay()
{
Super::BeginPlay();
downMode = new UGroundMode();
upMode = new UGroundMode();
leftMode = new UGroundMode();
rightMode = new UGroundMode();
}
When I attempt to create instances of UGroundMode with the new keyword I get the following compile error: D:\Documents\Unreal Projects\NMR\Source\NMR\PlayerPhysicsCollisionInfo.cpp(25) : error C2661: 'UGroundMode::operator new': no overloaded function takes 1 arguments
What am I doing wrong? The constructor takes no arguments not 1.
The new
expression, like you're doing here, does two things.
When it calls the allocation function for a class T
, it first determines the size of that class, std::size_t size
, and passes that as the first parameter to the allocation function. The allocation function for a class is the first resolved operator new()
function available to a class within its scope. Any optional placement params are then sent as the next parameters to the allocation function. Placement params are parentheses-enclosed expressions immediately after the new
keyword:
T* foo = new T(); // good old fashioned uncomplicated new
^
|
+---- wants to call a `operator new(std::size_t)` function
T* bar = new(1, 2) T(); // a little more complicated
^ ^
| |
| +----- these are placement params
+---------- wants to call `operator new(std::size_t, int, int)`
Your issue is when the new
expression tries to do the allocation and finds its appropriate operator new()
. Classes can override operator new()
, which your class does. The new
keyword will take sizeof(T)
, and attempt to send that as the first parameter to the class-defined operator new
function.
Where is that class-defined overloaded operator new()
function, you ask?
UObject
, which your class inherits from, has a void* UObject::operator new()
function declared that takes five, count 'em FIVE, parameters.
The new
keyword identifies this operator new()
as your class' operator new()
, but sees that you're only passing the one parameter (sizeof(T)
), and fails.
As described on the linked Unreal page, new
expressions are not to be used with UObject
objects. Use StaticConstructObject()
instead.
operator new
anywayIf you want to make Unreal engine even unrealer, you can specify an appropriate operator new
function by explicitly scoping it. You can attempt to access the global operator new()
function by putting the global scope indicator at the front of you new
statement:
downMode = ::new UGroundMode();
Of course, then you'll run into the problem that ::new UGroundMode()
, like any other new
operation, returns a UGroundMode*
which you're trying to store in a UGroundMode
object. This will fail. I don't know what it will do the Unreal engine. Probably bad things.
https://en.cppreference.com/w/cpp/language/new
https://en.cppreference.com/w/cpp/memory/new/operator_new