如何在不破坏移动和复制构造函数的情况下声明虚拟析构函数
How to declare the virtual destructor without breaking move and copy constructors
像这样将用户定义的默认虚拟析构函数添加到 class 时..
class Foo
{
public:
Foo();
virtual ~Foo() = default;
};
.. 它具有防止自动生成移动构造函数的副作用。复制构造函数的自动生成也被弃用。 像这样..
class Foo
{
public:
Foo();
virtual ~Foo() = default;
Foo(const Foo& /* other */) = default;
Foo&operator=(const Foo& /* other */) = default;
Foo(Foo&& /* other */) = default;
Foo&operator=(Foo&& /* other */) = default;
};
但是,这非常冗长且难以阅读。还有其他解决方案吗?
首先我会考虑Foo
是否真的需要一个虚拟析构函数。也许您可以使用一个简单的模板以类型安全的方式解决您的问题,避免弄乱指针和转换等。
如果您决定 Foo
虚拟化,那么我会推荐这种抽象。
class VirtualDestructor
{
protected:
VirtualDestructor() = default;
virtual ~VirtualDestructor() = default;
VirtualDestructor(const VirtualDestructor & /* other */) = default;
VirtualDestructor &operator=(const VirtualDestructor & /* other */) = default;
VirtualDestructor(VirtualDestructor && /* other */) = default;
VirtualDestructor &operator=(VirtualDestructor && /* other */) = default;
};
将其放入库中适当的 namespace
。然后你可以保持 Foo
和所有其他虚拟 类 干净。
class Foo : VirtualDestructor
{
public:
Foo();
};
删除例如复制构造函数时也可以使用相同的技术。
像这样将用户定义的默认虚拟析构函数添加到 class 时..
class Foo
{
public:
Foo();
virtual ~Foo() = default;
};
.. 它具有防止自动生成移动构造函数的副作用。复制构造函数的自动生成也被弃用。
class Foo
{
public:
Foo();
virtual ~Foo() = default;
Foo(const Foo& /* other */) = default;
Foo&operator=(const Foo& /* other */) = default;
Foo(Foo&& /* other */) = default;
Foo&operator=(Foo&& /* other */) = default;
};
但是,这非常冗长且难以阅读。还有其他解决方案吗?
首先我会考虑Foo
是否真的需要一个虚拟析构函数。也许您可以使用一个简单的模板以类型安全的方式解决您的问题,避免弄乱指针和转换等。
如果您决定 Foo
虚拟化,那么我会推荐这种抽象。
class VirtualDestructor
{
protected:
VirtualDestructor() = default;
virtual ~VirtualDestructor() = default;
VirtualDestructor(const VirtualDestructor & /* other */) = default;
VirtualDestructor &operator=(const VirtualDestructor & /* other */) = default;
VirtualDestructor(VirtualDestructor && /* other */) = default;
VirtualDestructor &operator=(VirtualDestructor && /* other */) = default;
};
将其放入库中适当的 namespace
。然后你可以保持 Foo
和所有其他虚拟 类 干净。
class Foo : VirtualDestructor
{
public:
Foo();
};
删除例如复制构造函数时也可以使用相同的技术。