【问题标题】:Constructor Asking for Wrong Number of Arguments构造函数要求错误数量的参数
【发布时间】:2020-09-09 23:15:08
【问题描述】:

我在 Unreal 中建立了一个名为 Groundmode 的类

地面模式.h: #pragma 一次

#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() {}

我希望能够在另一个类中实例化这个类。 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();
    }

当我尝试使用 new 关键字创建 UGroundMode 实例时,出现以下编译错误: D:\Documents\Unreal Projects\NMR\Source\NMR\PlayerPhysicsCollisionInfo.cpp(25) : 错误 C2661: 'UGroundMode::operator new': 没有重载函数需要 1 个参数

我做错了什么?构造函数不接受非 1 的参数。

【问题讨论】:

  • 您没有new UObjects,也没有按价值将它们存储在任何地方。请从一些基本的 UE c++ 教程开始。
  • 好像没有想过做教程。 :P 所有我能找到的都很烂。
  • @user 您是否搜索过 Epic 的认可材料? unrealengine.com/en-US/resources

标签: c++ unreal-engine4 unreal-development-kit


【解决方案1】:

new 表达式,就像您在这里所做的那样,有两件事。

  1. 它通过为该对象调用适当的分配函数来为该对象分配内存。
  2. 它在分配的内存中构造对象。

当它为类T 调用分配函数时,它首先确定该类的大小std::size_t size,并将其作为第一个参数传递给分配函数。类的分配函数是其范围内类可用的第一个解析的operator new() 函数。然后将任何可选的 placement params 作为下一个参数发送到分配函数。放置参数是紧跟在 new 关键字之后的括号括起来的表达式:

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)`

您的问题是new 表达式尝试进行分配并找到合适的operator new()。类可以覆盖operator new(),您的类可以这样做。 new 关键字将采用 sizeof(T),并尝试将其作为第一个参数发送到类定义的 operator new 函数。

你问那个类定义的重载 operator new() 函数在哪里?

Right here

UObject,您的类继承自,声明了一个 void* UObject::operator new() 函数,该函数接受五个,计数为五个,参数。

new 关键字将此 operator new() 标识为您的类的 operator new(),但发现您只传递了一个参数 (sizeof(T)),因此失败了。


解决方案

如链接的虚幻页面上所述,new 表达式不能与UObject 对象一起使用。请改用StaticConstructObject()


如果你想调用全局operator new 反正

如果你想让 Unreal 引擎甚至 unrealer,你可以通过明确的作用域来指定一个合适的 operator new 函数。您可以尝试通过将全局范围指示器放在 new 语句前面来访问全局 operator new() 函数:

downMode = ::new UGroundMode();

当然,然后您会遇到::new UGroundMode() 与任何其他new 操作一样返回一个您试图将其存储在UGroundMode 对象中的UGroundMode* 的问题。这将失败。我不知道虚幻引擎会做什么。可能是坏事。


进一步阅读

https://en.cppreference.com/w/cpp/language/new
https://en.cppreference.com/w/cpp/memory/new/operator_new

【讨论】:

  • AFAIK 你应该打电话给NewObject&lt;T&gt;,而不是StaticConstructObject。此外,您应该将任何UObjects 指定为UPROPERTY,并且可以使用Instanced 属性说明符标记它们,以便在包含类中自动构造对象。
  • @Rotem 随时编辑答案。我对虚幻一无所知。
  • @Rotem 如果你说的是这样的话,而不是做一个学习编码风格的评论,那就太好了。谢谢,但我会尝试,因为我无法让 StaticConstructObject 工作。一旦我弄清楚了,我会编辑答案。
  • @user2725919 我最初的评论并没有刻薄或轻蔑的意思,如果遇到这种情况,我很抱歉。听起来您正处于使用 UE 的阶段,阅读有关 UObjects 的介绍性 c++ 文档会更好地为您服务。
  • @Rotem 好的,很抱歉反应过度。由于学习虚幻的资源有限,这令人沮丧。除了直接文档之外,关于如何在 C++ 上使用蓝图的大量信息很少。我将阅读有关 UObjects 的文档。
猜你喜欢
  • 2012-04-18
  • 1970-01-01
  • 2014-07-06
  • 1970-01-01
  • 2012-03-25
  • 1970-01-01
  • 1970-01-01
  • 2021-04-13
相关资源
最近更新 更多