Joh*_*ien 2 c++ raii c++20 stdoptional
假设我有一个 RAII 类,其实例永远不应该被复制:
class Session {
public:
Session(); // Allocates a resource and sets generates a unique Session::id.
~Session(); // Frees the resource
Session(const Session&) = delete;
Session& operator = (Session&) = delete;
private:
std::uint32_t id;
}
Run Code Online (Sandbox Code Playgroud)
鉴于我不能允许复制,我想允许移动,所以我需要实现移动构造函数和移动赋值运算符,但我不确定应该如何处理Session::id移动的实例。
我可以:
-1无效值)std::optional并将其设置为std::nullopt使其无效。这些选项中哪一个(如果有的话)是正确的?
std::optional由于这可以通过牺牲 2 32个可能的s 中的一个值来完成id,因此我确实希望使用std::string::npos来初始化一个无符号类型的常量。id-1
例子:
class Session {
public:
// the constant used to signal an invalid id:
static constexpr std::uint32_t invalid_id = static_cast<std::uint32_t>(-1);
Session() :
id(id_counter++)
/* allocate the resource */
{}
Session(const Session&) = delete;
Session(Session&& other) noexcept :
id(std::exchange(other.id, invalid_id)) // exchange with the invalid id
/* move or exchange the resource */
{}
Session& operator=(const Session&) = delete;
Session& operator=(Session&& other) noexcept {
// check for self-assignment if needed
std::swap(id, other.id);
// swap the resource
return *this;
}
~Session() {
if(id != invalid_id) { // if the check is even needed
/* free the resource */
}
}
private:
inline static std::uint32_t id_counter = 0;
std::uint32_t id;
};
Run Code Online (Sandbox Code Playgroud)
一个选择是让0ifinvalid_id在您的情况下感觉更自然。您只需使用 进行初始化invalid_id并将0id 计数更改为id(++id_counter)。