Testing after taking in account @KaidoomDev 's advice results in this correct code for defining components in C++ at build time:
// some .h file
class AMyCustomActor : public AActor
{
GENERATED_BODY()
public:
AMyCustomActor::AMyCustomActor()
{
Root = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
SetRootComponent(Root);
SomeStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SomeStaticMesh"));
SomeStaticMesh->SetupAttachment(Root);
SomeActorComponent = CreateDefaultSubObject<UActorComponent>(TEXT("SomeActorComponent"));
};
protected:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
TObjectPtr<USceneComponent> Root;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
TObjectPtr<UStaticMeshComponent> SomeStaticMesh;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
TObjectPtr<UActorComponent> SomeActorComponent;
// ...
And at runtime, the following works:
// the `FName` needs to be unique, therefore I construct it using the loop index `i`
const auto SplineMesh = NewObject<USplineMeshComponent>(this, *FString(TEXT("SplineMesh")).Append(FString::FromInt(i)));
// if I don't register here, the spline mesh doesn't render
SplineMesh->RegisterComponent();
SplineMesh->AttachToComponent(Root, FAttachmentTransformRules::KeepWorldTransform);
// if I don't add instance here, the spline meshes don't show in the component list in the editor
AddInstanceComponent(SplineMesh);
// specific set up of spline mesh component
SplineMesh->SetMobility(EComponentMobility::Stationary);
SplineMesh->CastShadow = false;
SplineMesh->SetStaticMesh(SM_Trajectory);
const auto VecStartPos = Spline->GetLocationAtSplinePoint(Indices[i], ESplineCoordinateSpace::World);
const auto VecStartDirection = Spline->GetTangentAtSplinePoint(Indices[i], ESplineCoordinateSpace::World);
const auto VecEndPos = Spline->GetLocationAtSplinePoint(Indices[i + 1], ESplineCoordinateSpace::World);
const auto VecEndDirection = Spline->GetTangentAtSplinePoint(Indices[i + 1], ESplineCoordinateSpace::World);
SplineMesh->SetStartAndEnd(VecStartPos, VecStartDirection, VecEndPos, VecEndDirection);