x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

UE4 C++ Getters for objects have issues with blueprints?

Here my class. It's an actor component that I am attaching to an object. This is the .h file:

 // Fill out your copyright notice in the Description page of Project Settings.
 
 #pragma once
 
 #include "HealthSubsystem.h"
 #include "CoreMinimal.h"
 #include "Components/ActorComponent.h"
 #include "SurvivalSystemComponent.generated.h"
 
 
 UCLASS(ClassGroup=SurvivalSystemComponents, meta=(BlueprintSpawnableComponent), Blueprintable)
 class CUSTOMTPC_API USurvivalSystemComponent : public UActorComponent
 {
     GENERATED_BODY()
 
 private:
     ///<summary>
     /// Health subsystem
     ///</summary>
     UPROPERTY(EditAnywhere, Category = "Survival subsystems")
         UHealthSubsystem* Health;
 
 public:    
     // Sets default values for this component's properties
     USurvivalSystemComponent();
      
     //This is a pointer -> to a -> [constant UHealthSusbsytem]
     UFUNCTION(BlueprintCallable, Category = "Survival subsystem methods")
         UHealthSubsystem const* GetHealthSubsystem() const;
 
      
 protected:
     // Called when the game starts
     virtual void BeginPlay() override;
 
 public:    
     // Called every frame
     virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
 
 };
 


Ok and here is the .cpp file

 // Fill out your copyright notice in the Description page of Project Settings.
 
 #include "SurvivalSystemComponent.h"
 #include "EngineMinimal.h"
 
 #define DISPLAY_MESSAGE(message) if(GEngine){GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Yellow, TEXT(message));} 
 
 // Sets default values for this component's properties
 USurvivalSystemComponent::USurvivalSystemComponent()
 {
     // Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
     // off to improve performance if you don't need them.
     PrimaryComponentTick.bCanEverTick = true;
     // ...
 }
 
 
 
 
 UHealthSubsystem const* USurvivalSystemComponent::GetHealthSubsystem() const
 {
     return Health;
 }
 
 // Called when the game starts
 void USurvivalSystemComponent::BeginPlay()
 {
     Super::BeginPlay();
 
     if (Health == nullptr) 
     {
         Health = NewObject<UHealthSubsystem>();
         Health->Initialize(100,100, 0, 0, true);
     }
 }
 
 // Called every frame
 void USurvivalSystemComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
 {
     Super::TickComponent(DeltaTime, TickType, ThisTickFunction); 
 
     if (Health != nullptr)
     {
         Health->SetDepletionRate(DeltaTime * 0.05f * 100);
         Health->DepleteHealth();
     }        
 }
 
 

Focus on the UHealthSubsystem object called Health. Also focus on the method GetHealthSubsystem();

The intent of that getter method is to return a pointer to a constant UHealthSubsystem. That means that you cannot use setter methods if you were to call GetHealthSubsystem. The syntax on where I put the const modifier keyword is based off the clockwise/spiral rule. Essentially you need to read it backwards, that is:

UHealthSubsystem const* GetHealthSubsystem() const; [Note, the const at the end of course means that this method shouldn't be modifying the class.]

This statement, if you read it right to left says "pointer to a constant UHealthSubsystem".

So if I call GetHealthSubsystem().SomeSetterMethod(someValue), it shouldn't work. I am mutating the object itself.

This is my intent. I also want to make it so that blueprints can read this object. If i didn't put the UFUNCTION macro, everything complies. However, if i left it there, I get this compile error : "Cannot convert from const UHealthSubsystem* to UHealthSubsystem*". "Conversion loses qualifiers" "Cannot convert from const UHealthSubsystem* to UHealthSubsystem*". "Conversion loses qualifiers"

Why is this happening? Why does the compiler not understand that I am only going to return a immutable UHealthSubsystem pointer, who's object that it is pointing to cannot be modified (although of course, the pointer itself can point to a different object).

Also, if I put the const keyword AFTER the "*" symbol, it compiles fine. Of course, why would I even be using this? This is saying that I can mutate the object but I can't change where it points to.

And YES, UHealthSubsystem is a UObject. In fact, it inherits from a class called BaseSystem which is what inherits UObject.

Another note: It tell's me the error comes from line 14 on the .h file. 0_0.

Here's the error messages :

 Info Compiling game modules for hot reload
 Info Parsing headers for CustomTPCEditor
 Info   Running UnrealHeaderTool "F:\Projects\Unreal Projects\CustomTPC\CustomTPC.uproject" "F:\Projects\Unreal Projects\CustomTPC\Intermediate\Build\Win64\CustomTPCEditor\Development\CustomTPCEditor.uhtmanifest" -LogCmds="loginit warning, logexit warning, logdatabase error" -Unattended -WarningsAsErrors -installed
 Info Reflection code generated for CustomTPCEditor in 3.9255561 seconds
 Info Performing 4 actions (4 in parallel)
 Info CustomTPC.generated.cpp
 Info SurvivalSystemComponent.cpp
 Error F:\Projects\Unreal Projects\CustomTPC\Source\CustomTPC\Public\SurvivalSystem\SurvivalSystemComponent.h(14) : error C2440: '=': cannot convert from 'const UHealthSubsystem *' to 'UHealthSubsystem *'
 Error F:\Projects\Unreal Projects\CustomTPC\Source\CustomTPC\Public\SurvivalSystem\SurvivalSystemComponent.h(14) : note: Conversion loses qualifiers
 Error F:\Projects\Unreal Projects\CustomTPC\Source\CustomTPC\Public/SurvivalSystem/SurvivalSystemComponent.h(14) : error C2440: '=': cannot convert from 'const UHealthSubsystem *' to 'UHealthSubsystem *'
 Error F:\Projects\Unreal Projects\CustomTPC\Source\CustomTPC\Public/SurvivalSystem/SurvivalSystemComponent.h(14) : note: Conversion loses qualifiers
 Info ERROR: UBT ERROR: Failed to produce item: F:\Projects\Unreal Projects\CustomTPC\Binaries\Win64\UE4Editor-CustomTPC-668.dll
 Info Total build time: 9.21 seconds (Local executor: 0.00 seconds)
 

Product Version: UE 4.16
Tags:
more ▼

asked Jun 03 '17 at 09:07 PM in C++ Programming

avatar image

nerdares
6 2 4 9

avatar image nerdares Jun 05 '17 at 01:34 AM

bump..

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Well, this is not const: UPROPERTY(EditAnywhere, Category = "Survival subsystems") UHealthSubsystem* Health;

That is why it fails to compile. It has nothing to do with Blueprints, it is a problem with your C++ code.

HTH

more ▼

answered Jun 03 '17 at 09:17 PM

avatar image

NoobsDeSroobs
2.7k 107 35 180

avatar image nerdares Jun 03 '17 at 09:28 PM

If I did that, then I can't call the mutator methods from my cpp file, such as Initialize(), and SetDepletionRate(). I commented those methods out anyways. I changed the :

UPROPERTY(EditAnywhere, Category = "Survival subsystems") UHealthSubsystem* Health;

to

UPROPERTY(EditAnywhere, Category = "Survival subsystems") UHealthSubsystem const* Health;

and I actually still get the same compiler errors as up top. However, if I take out both the UPROPERTY and UFUNCTION macros, it compiles

avatar image NoobsDeSroobs Jun 05 '17 at 01:41 AM

Try returning a non const object, but instead return a singleton pointer to the object. You can return a const pointer to a static pointer that can only be set once.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question