gpt4 book ai didi

c++ - 手动生命周期管理,替代安置

转载 作者:行者123 更新时间:2023-12-03 06:57:47 25 4
gpt4 key购买 nike

我有一段带有回调的低级代码:InitCleanup以及其他。我不控制回调的参数。我选择使用全局变量来管理状态,例如class state
这是我可以使用的简单构造:

std::unique_ptr<state> s;
void Init() {
s = make_unique<state>();
}
void Cleanup() {
s.reset();
}
这很简单,很容易解释。主要缺点:它使用堆,这意味着会牺牲性能,并且分配可能会失败。
另外,我可以使用类似于以下内容的构造:
alignas(state) unsigned char s_buf[sizeof(state)];
void Init() {
state* s = new(s_buf) state;
}
void Cleanup() {
state* s = reinterpret_cast<state*>(s_buf);
s->~T();
}
现在,我不使用堆,但是它比较丑陋,而且更容易出错,而且我甚至不确定是否存在潜伏在某处的未定义行为。我也许可以将其封装在包装器类中,但是有很多地方可能出错。
是否有任何常用的构造来实现我要执行的操作,即具有类似 unique_ptr的类但没有堆分配?

最佳答案

将评论扩展为答案:
C++ 17为此提供了完美的工具: std::optional
它完全可以执行您的操作,除了它还可以跟踪存储中当前是否有对象。除非您要进行嵌入并且标志的额外大小很重要,否则应该很好:

#include <optional>

struct state {
int foo;
};

static std::optional<state> currentState;

void Init() {
currentState = state{ 42 };
}

void CleanUp() {
currentState = std::nullopt;
}

void doStuff() {
currentState->foo += 12;
}

void doStuffOnlyIfInitialized() {
if (currentState) {
currentState->foo += 12;
}
}
请注意,如果您两次调用 Init或两次调用 CleanUp,则此处的代码将很高兴。如果要防止这种情况,可以在 assert(!currentState)的开头添加 Init,在 assert(currentState)的开头添加 CleanUp

关于c++ - 手动生命周期管理,替代安置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64288246/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com