DEV Community

Haris
Haris

Posted on

Move Semantics In Unreal Engine

The Copy Problem

In traditional C++ 98 programming you had two ways in which objects were created: From scratch and from copying.

Foo(); // Default Ctor
Foo(int x); // Parameterized Ctor
Foo(const Foo& rhs); // Copy Ctor
Foo& operator=(const Foo& rhs); // Copy Assignment
Enter fullscreen mode Exit fullscreen mode

Copying is usually more processor intensive to overcome this in C++ 11 move semantics were invented.

Foo(Foo&& rhs); // Move Ctor
void operator=(Foo&& rhs); // Move Assignment
Enter fullscreen mode Exit fullscreen mode

Moving objects is more memory efficient than copying (not every time).

When to Implement Special Functions

Deciding for which types to implement custom move constructors basically boils down to following the Rule of Three/Five/Zero, Just ask yourself one question: Does your type deal with ownership? Or, alternatively: Does your type allocate and/or manage (dynamic) resources?

For Plain old datatypes
For POD types or POD type members, moving is the same as copying. Imagine the difference between adding instances of either of the following two types to a std::vector:

// when added, the pointer to the dynamic memory allocation of numbers can be copied to the new instance in the vector
// sizeof(Foo) = 24 with gcc on Win64
// no reallocation necessary = possible performance gain
struct Foo
{
    // dynamic vector with 1000 entries
    std::vector<int> numbers;
}

// When added, a full copy must be performed
// sizeof(Bar) = 4000 with gcc on Win64
// All 1000 bytes need to be copied
struct Bar
{
    int numbers[1000];
}
Enter fullscreen mode Exit fullscreen mode

Unreal Engine Terminology

Unreal engine is a bit different when it comes to naming convention and even has some extra functionality

Smart pointers are encouraged to be used with not blueprint exposed code whenever it adds clarity and simplifies object lifetime management. The Unreal equivalents to std smart pointers are:

  • TUniquePtr
  • TSharedPtr
  • TWeakPtr

It’s worth noting that all of this is not usable in the following contexts:

  • UObjects cannot be moved or referenced by smart pointers as they are always referenced by pointer and managed by the garbage collector.
  • Functions with r-value-reference or smart pointer parameters are not Blueprint exposable.
  • UStructs may define custom move functionality, but rarely benefit from it, because they usually are plain data structs.

Top comments (0)