从抽象(纯虚)类私有继承有意义吗?
does it make sense to inherit privately from an abstract (pure virtual) class?
假设这个结构
struct InterfaceForFoo
{
virtual void GetItDone() = 0;
};
class APoliticallyCorrectImplementationOfFooRelatedThings : private InterfaceForFoo
{
public:
void GetItDone() { /*do the thing already*/ };
};
现在,我想知道以这种方式从接口私有继承是否有任何有用的场景。
嗯,这里每个人都说"不"。我说:"是的,它确实有意义。"
class VirtualBase {
public:
virtual void vmethod() = 0;
// If "global" is an instance of Concrete, then you can still access
// VirtualBase's public members, even though they're private members for Concrete
static VirtualBase *global;
};
// This can also access all of VirtualBase's public members,
// even if an instance of Concrete is passed in,
void someComplicatedFunction(VirtualBase &obj, ...);
class Concrete : private VirtualBase {
private:
virtual void vmethod();
public:
void cmethod() {
// This assignment can only be done by Concrete or friends of Concrete
VirtualBase::global = this;
// This can also only be done by Concrete and friends
someComplicatedFunction(*this);
}
};
继承private
并不意味着你不能从类外部访问VirtualBase
的成员,它只意味着你不能通过对Concrete
的引用访问这些成员。但是,Concrete
和它的朋友可以将Concrete
的实例强制转换为VirtualBase
,这样任何人都可以访问公共成员。简单,
Concrete *obj = new Concrete;
obj->vmethod(); // error, vmethod is private
VirtualBase *obj = VirtualBase::global;
obj->vmethod(); // OK, even if "obj" is really an instance of Concrete
问题是为什么基类只有纯虚方法很重要?
这两件事几乎没有关系。私有意味着它是类的实现细节,而不是公共接口的一部分,但您可能希望将接口实现为实现细节。假设您编写了一个类,并且您决定通过需要您实现接口的库来实现该功能。这是一个实现细节,没有必要仅仅因为接口只有纯虚函数而将继承设为public 。
在面向对象方面,对于抽象的class
,没有private
继承的用例。
然而,如果你想强制你的子class
必须派生某些方法,那么你可以使用这个。例如:
struct implement_size
{
virtual size_t size () = 0;
};
class MyVector : private implement_size
{
public:
size_t size () { ... } // mandatory to implement size()
}
class MyString : private implement_size
{
public:
size_t size () { ... } // mandatory to implement size()
};
所以,它只是有助于维护个人编码纪律。这个例子传递的信息是,继承不仅仅是为了面向对象的目的。您甚至可以使用继承来停止继承链(类似于Java final)。
嗯?不,这完全没有意义,因为您提供接口的原因是希望其他人通过该接口使用您的类。如果他们不知道你在执行它,那该怎么做呢?
#include <vector>
class Fooable{
public:
virtual void foo() = 0;
};
class DoesFoo
: private Fooable
{
void foo();
};
int main(){
std::vector<Fooable*> vf;
vf.push_back(new DoesFoo()); // nope, doesn't work
vf[0]->foo();
}
上面的示例不起作用,因为外部世界不知道DoesFoo
是Fooable
,因此您不能new
它的实例并将其分配给Fooable*
。
不完全是。如果你需要一个函数,你就实现它。强制一个不能被其他类使用的函数是没有意义的。
为什么要从接口中私有继承,我不知道;这有点违背了接口的目的。
如果它不是一个接口,而是一个类,它是有意义的:
class A {
virtual void foo() = 0;
void bar() {
foo();
}
};
class B : private A {
virtual void foo() {
}
};
相关文章:
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- API 返回智能指针的 std::optional 以明确指定指针可能为 null 是否有意义?
- 从头开始为应用程序创建 docker 映像是否有意义?
- 当子类需要在 c++ 中相互包含时,继承有缺陷
- 在c++中,如果首先禁止默认构造,那么禁止复制构造有意义吗
- sizeof(函数)有意义吗?
- 二进制模式 + 格式化文本操作或文本模式 + 二进制数据操作 - 有意义吗?
- 插入向量时,使用lambda的返回而不是函数的返回是否有意义?
- 在 C++17 中使用 const std::string& 参数有意义吗?
- 基础类模板参数的有意义名称
- 内联这个函数,确实有意义
- 将 final 关键字添加到没有基类(未派生)的类中的虚函数是否有意义
- 左移负整数为零是否有意义?
- 是否有一个上下文表达式`a.b :: c`有意义
- 是否有一些有意义的统计数据来证明保持有符号整数算术溢出未定义是合理的
- 将可选与reference_wrapper相结合是否有意义?
- 函数返回rvalue参考是否有意义
- 多层继承在C 中是否有意义
- 从 STL 容器继承并删除"新"运算符以防止由于缺少虚拟析构函数而导致未定义的行为是否有意义?
- 从抽象(纯虚)类私有继承有意义吗?