C++ abstract 类 需要遵守五规则吗?
Do C++ abstract classes need to obey the rule of five?
像这样实现抽象 class 时:
class Base
{
public:
virtual ~Base() = default;
virtual void foo() = 0;
};
这个接口是否必须遵守五规则,即我是否必须添加复制构造函数、复制赋值运算符、移动构造函数和移动赋值运算符?
我认为 Base
类型的实例由于纯虚拟成员函数而无法实例化,因此为其他特殊成员函数提供默认实现可能没有实际用途。
是否有任何use-case/example需要我提供其他特殊成员函数?
其实恰恰相反。我会考虑删除 class 的复制和分配,它应该只是一个接口 class 以避免切片。考虑
class Base {
public:
virtual ~Base() {}
};
class D1 : public Base {
int i;
public:
~D1() override {}
};
class D2 : public Base {
int i;
double d;
public:
~D2() override {}
};
你可以这样写
vector<Base> vec;
D1 d;
D2 e;
vec.push_back(d);
vec.push_back(e);
。您会尝试将大小为 D2 的对象压缩成一个小得多的 base 类型对象。通过删除副本和分配,您可以防止用户或您自己这样做。
"abstract" 与此处无关。如果 class 具有默认版本无法正确复制的数据,则它需要自己的复制构造函数、复制赋值运算符等。句号。纯虚函数的存在与否不会改变这一点。您的示例没有任何数据,因此这里没有问题。
像这样实现抽象 class 时:
class Base
{
public:
virtual ~Base() = default;
virtual void foo() = 0;
};
这个接口是否必须遵守五规则,即我是否必须添加复制构造函数、复制赋值运算符、移动构造函数和移动赋值运算符?
我认为 Base
类型的实例由于纯虚拟成员函数而无法实例化,因此为其他特殊成员函数提供默认实现可能没有实际用途。
是否有任何use-case/example需要我提供其他特殊成员函数?
其实恰恰相反。我会考虑删除 class 的复制和分配,它应该只是一个接口 class 以避免切片。考虑
class Base {
public:
virtual ~Base() {}
};
class D1 : public Base {
int i;
public:
~D1() override {}
};
class D2 : public Base {
int i;
double d;
public:
~D2() override {}
};
你可以这样写
vector<Base> vec;
D1 d;
D2 e;
vec.push_back(d);
vec.push_back(e);
。您会尝试将大小为 D2 的对象压缩成一个小得多的 base 类型对象。通过删除副本和分配,您可以防止用户或您自己这样做。
"abstract" 与此处无关。如果 class 具有默认版本无法正确复制的数据,则它需要自己的复制构造函数、复制赋值运算符等。句号。纯虚函数的存在与否不会改变这一点。您的示例没有任何数据,因此这里没有问题。