假设这个构造
struct InterfaceForFoo
{
virtual void GetItDone() = 0;
};
class APoliticallyCorrectImplementationOfFooRelatedThings : private InterfaceForFoo
{
public:
void GetItDone() { /*do the thing already*/ };
};
现在,我想知道以这种方式从接口私下继承是否有任何有用的场景。
答案 0 :(得分:5)
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
的成员,这只意味着您无法通过对{{{{}}的引用来访问这些成员1}}。但是,Concrete
及其朋友可以将Concrete
的实例投射到Concrete
,然后任何人都可以访问公共成员。简单地说,
VirtualBase
答案 1 :(得分:1)
在面向对象方面,抽象private
的此类class
继承没有用例。
但是,如果您想强制要求您的孩子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()
};
因此,它只是有助于维持个人编码规则。这个例子的消息是,继承不仅仅是面向对象的目的。你甚至可以use inheritance for stopping inheritance chain(类似于Java final)。
答案 2 :(得分:1)
问题是为什么基类只有纯虚方法才重要?
这两件事几乎无关。 Private表示它是您的类的实现细节,而不是公共接口的一部分,但您可能希望将接口实现为实现细节。考虑您编写一个类,并决定通过需要实现接口的库来实现该功能。这是一个实现细节,不需要继承public 只是因为接口只有纯虚函数。
答案 3 :(得分:0)
嗯?不,这完全没有意义,因为您提供界面的原因是您希望其他人通过该界面使用您的类 。如果他们不知道你实现它会如何工作?
#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*
。
答案 4 :(得分:-1)
不是真的。如果您需要一个功能,您可以实现它。强制使用其他类无法使用的函数是没有意义的。
为什么你会私下从界面继承,我不知道;这种做法违背了接口的目的。
如果它不是一个界面,而是一个类,那就有意义了:
class A {
virtual void foo() = 0;
void bar() {
foo();
}
};
class B : private A {
virtual void foo() {
}
};