如何删除 C++ 中 class 的所有隐式(默认)方法?
How to delete all implicit (default) methods of class in C++?
C++编译器在某些条件下为class添加隐式默认构造函数、复制构造函数、析构函数、转换运算符、赋值运算符等以及其他隐式方法。
如何以最短的方式disable/delete所有可能的隐式方法?
我不希望我的 class 不可复制,我只想禁用这些默认方法,以便编译器抛出编译错误,然后我自己实现它们。我只想过度控制,这样编译器就不会对我的 class.
做任何静默工作
例如我可以做下一件事(这只是一个虚拟的例子,在现实生活中我可以有任何复杂的class):
class C {
private:
C() = delete;
C(C const & other) = delete;
C & operator = (C const & other) = delete;
};
但这是很长的路要走,而且我可能会忘记删除一些方法签名,我需要删除所有方法签名。所以我自己从头开始重新实现所有方法。
而且我需要查看其他代码 needs/uses 和我尚未实现的所有方法的错误,而不是编译器默默地为我实现这些方法。
此外,如果我像上面示例中那样删除默认方法,我如何确定没有其他静默创建的方法?在线是否有编译器静默创建的 100% 所有标准方法的列表?
您可能会选择混合方法。定义繁琐class一次
class DeleteAllSpecialMemebers {
private:
DeleteAllSpecialMemebers() = delete;
DeleteAllSpecialMemebers(DeleteAllSpecialMemebers const &) = delete;
DeleteAllSpecialMemebers & operator = (DeleteAllSpecialMemebers const &) = delete;
DeleteAllSpecialMemebers(DeleteAllSpecialMemebers &&) = delete;
DeleteAllSpecialMemebers & operator = (DeleteAllSpecialMemebers &&) = delete;
protected:
struct token { explicit token() = default; };
DeleteAllSpecialMemebers(token) {}
};
然后从中继承:
class C : private DeleteAllSpecialMemebers{
public:
C(int) : DeleteAllSpecialMemebers(token{}) {}
};
额外的 token
类型允许派生 classes 来实现 other 构造函数,例如 C::C(int)
(甚至是用户-提供 C::C()
).
最短的选择可能是拥有一个可重复使用的虚拟底座 class:
struct NoSpecialMember {
NoSpecialMember(const NoSpecialMember&) = delete;
NoSpecialMember& operator=(const NoSpecialMember&) = delete;
NoSpecialMember(NoSpecialMember&&) = delete;
NoSpecialMember& operator=(NoSpecialMember&&) = delete;
~NoSpecialMember() = default;
};
继承private
ly就够了;
class Test : private NoSpecialMember {};
结果如下:
static_assert(!std::is_copy_constructible_v<Test>);
static_assert(!std::is_copy_assignable_v<Test>);
static_assert(!std::is_move_constructible_v<Test>);
static_assert(!std::is_move_assignable_v<Test>);
定义 helper 并将其用作 class 应禁用的字段:
struct DisableCopyAssign
{
DisableCopyAssign(char){}
DisableCopyAssign(const DisableCopyAssign&) = delete;
DisableCopyAssign(DisableCopyAssign&&) = delete;
};
class Foo
{
private:
DisableCopyAssign dummy;
};
C++编译器在某些条件下为class添加隐式默认构造函数、复制构造函数、析构函数、转换运算符、赋值运算符等以及其他隐式方法。
如何以最短的方式disable/delete所有可能的隐式方法?
我不希望我的 class 不可复制,我只想禁用这些默认方法,以便编译器抛出编译错误,然后我自己实现它们。我只想过度控制,这样编译器就不会对我的 class.
做任何静默工作例如我可以做下一件事(这只是一个虚拟的例子,在现实生活中我可以有任何复杂的class):
class C {
private:
C() = delete;
C(C const & other) = delete;
C & operator = (C const & other) = delete;
};
但这是很长的路要走,而且我可能会忘记删除一些方法签名,我需要删除所有方法签名。所以我自己从头开始重新实现所有方法。
而且我需要查看其他代码 needs/uses 和我尚未实现的所有方法的错误,而不是编译器默默地为我实现这些方法。
此外,如果我像上面示例中那样删除默认方法,我如何确定没有其他静默创建的方法?在线是否有编译器静默创建的 100% 所有标准方法的列表?
您可能会选择混合方法。定义繁琐class一次
class DeleteAllSpecialMemebers {
private:
DeleteAllSpecialMemebers() = delete;
DeleteAllSpecialMemebers(DeleteAllSpecialMemebers const &) = delete;
DeleteAllSpecialMemebers & operator = (DeleteAllSpecialMemebers const &) = delete;
DeleteAllSpecialMemebers(DeleteAllSpecialMemebers &&) = delete;
DeleteAllSpecialMemebers & operator = (DeleteAllSpecialMemebers &&) = delete;
protected:
struct token { explicit token() = default; };
DeleteAllSpecialMemebers(token) {}
};
然后从中继承:
class C : private DeleteAllSpecialMemebers{
public:
C(int) : DeleteAllSpecialMemebers(token{}) {}
};
额外的 token
类型允许派生 classes 来实现 other 构造函数,例如 C::C(int)
(甚至是用户-提供 C::C()
).
最短的选择可能是拥有一个可重复使用的虚拟底座 class:
struct NoSpecialMember {
NoSpecialMember(const NoSpecialMember&) = delete;
NoSpecialMember& operator=(const NoSpecialMember&) = delete;
NoSpecialMember(NoSpecialMember&&) = delete;
NoSpecialMember& operator=(NoSpecialMember&&) = delete;
~NoSpecialMember() = default;
};
继承private
ly就够了;
class Test : private NoSpecialMember {};
结果如下:
static_assert(!std::is_copy_constructible_v<Test>);
static_assert(!std::is_copy_assignable_v<Test>);
static_assert(!std::is_move_constructible_v<Test>);
static_assert(!std::is_move_assignable_v<Test>);
定义 helper 并将其用作 class 应禁用的字段:
struct DisableCopyAssign
{
DisableCopyAssign(char){}
DisableCopyAssign(const DisableCopyAssign&) = delete;
DisableCopyAssign(DisableCopyAssign&&) = delete;
};
class Foo
{
private:
DisableCopyAssign dummy;
};