To expand on [USER=“434”]BrUnO XaVIeR[/USER]'s explanation, in C++ objects can be allocated on the stack, inline in other objects or on the heap. A stack/inline object is created without a new keyword and is not a pointer:
MyClass myObject = MyClass();
Both cases will call the MyClass’ default constructor. The variable myObject is treated as a value: if you assign it to another MyClass variable, C++ will copy the object. If myObject is a local variable inside a function, method, or if/for/while/etc block, it will be destructed automatically when it goes out of scope. If it’s a property in another class, it will be is destructed when the instance of that class is destructed. This is very simple to work with, but obviously it’s not viable for complex objects and objects that need to be accessed from various places. For that you use heap-allocated objects:
MyClass* myHeapObject = new MyClass();
The new keyword allocates heap memory, constructs a MyClass object there and returns its address (the infamous pointer). The thing is, unlike garbage-collected languages like C# and Java, in C++ it’s the application responsibility to manage memory allocations.
If myHeapObject is a local variable inside a function, the object it points to will not be automatically deleted when the function returns and you will have a memory leak. This is a “dumb” pointer: it stores only the address (a number) to the object memory. Somewhere, your code need to delete the object when it’s no longer needed:
But what if you shared this pointer with other variables?
MyClass* anotherPointer = myHeapObject;
delete anotherPointer; // CRASH!
Like said before, pointers are just numbers. The delete keyword just destructs the object at the address you pass to it, it doesn’t touch the value of myHeapObject and much less of anotherPointer. Working with pointers, you need to be mindful of which part of your code has the responsibility of destroying each object.
Smart/shared pointers are tools to create safer pointers to help with this problem by wrapping a pointer inside a value type, using the inline/stack automatic constructor/copy/destructor calls to manage the lifetime of a heap-allocated object. You have a struct that stores a pointer to an object, and a pointer to an integer to count references. In the copy constructor, the object and counter pointers are copied and the reference counter is incremented, and in the destructor the counter is decremented. If the counter reaches zero, the pointer and the counter are deleted. This is a simple implementation, there are other variants (like weak pointers, which store a shared reference but don’t increment the count and can detect if the object has been destroyed elsewhere).
UE4 has it’s own memory management system for the UObject class, which is why you cannot create UObjects with the standard “new” keyword, or allocate them inline inside other classes/structs or in the stack.