C ++以定义明确的方式将堆上的对象移动到本地对象中

C++ moving object on heap into local object in a well defined manner

是否可以将可移动堆实例移动到本地对象中?我有下面的示例代码:

#include <memory>
#include <type_traits>
#include <concepts>
#include <string>

template<std::move_constructible T>
struct LazyGuard
{
    T value;
    LazyGuard(T* const ptr) : value(std::move(*ptr)) { }
};

template <std::move_constructible T>
inline T&& MakeLocal(T* ptr)
{
    return std::move(*ptr);
}

int main()
{
    LazyGuard<std::string> guard(new std::string("Will be using with 'Socket* TCPSocket::FromAddress' kind of constructors"));
    // Or another way
    std::string local2 = MakeLocal(new std::string("similar thing"));
    // Or another way
    std::string local3(MakeLocal(new std::string("similar thing")));
    return 0;
}

我想知道的是:

我知道可以使用智能指针,但这不是我在这里要问的。

更新:为了解决泄漏问题,我在守卫构造函数中添加了 delete,因此改进了下面的示例。我找不到用“MakeLocal”示例执行此操作的方法,这有可能吗?:

template<std::move_constructible T>
struct LazyGuard
{
    T value;
    LazyGuard(T* const ptr) : value(std::move(*ptr)) { delete ptr; }
};


int main()
{
    LazyGuard<std::string> guard(new std::string("Will be using with 'Socket* TCPSocket::FromAddress' kind of constructors"));
    return 0;
}

Can we guarantee the move constructor (or move assignment operator) will be called?

就内存 allocation/deallocation 而言,堆与堆栈仅“意味着”任何事情。除此之外,它们实际上是无法区分的。一个对象是一个对象,无论它的内存位于何处。

对象从堆到堆、从栈到栈、从堆到栈、从栈到堆没有区别

简而言之:是的,您可以从堆上的实例安全地移动构造或移动分配基于堆栈的对象。

Is the code well-defined, or can it be made well-defined?

定义明确,但不规范。

注意我说的是move-construct。这不会破坏堆上的对象,只是将其 content 移动到堆栈。您仍然需要销毁原始对象。

就目前而言,您的代码正在泄漏大量内存。

编辑LazyGuard 的更新构造函数将工作 而不会泄漏内存。但是,构造函数获取原始指针的所有权是非常非常糟糕的设计。

LazyGuard真的应该这样写:

template<std::move_constructible T>
struct LazyGuard
{
    T value;
    LazyGuard(T v) : value(std::move(v)) {}
};

它的初始化器来自哪里是它业务的none,这是它用在哪里的问题。