从抽象(纯虚拟)类私下继承是否有意义?

时间:2011-07-10 17:50:31

标签: c++ abstract-class virtual-method private-inheritance

假设这个构造

struct InterfaceForFoo
{
    virtual void GetItDone() = 0;
};


class APoliticallyCorrectImplementationOfFooRelatedThings : private InterfaceForFoo
{

  public:
    void GetItDone() { /*do the thing already*/ };   
};

现在,我想知道以这种方式从接口私下继承是否有任何有用的场景。

5 个答案:

答案 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();
}

以上示例不起作用,因为外界不知道DoesFooFooable,因此您不能new它的实例并将其分配给Fooable*

答案 4 :(得分:-1)

不是真的。如果您需要一个功能,您可以实现它。强制使用其他类无法使用的函数是没有意义的。

为什么你会私下从界面继承,我不知道;这种做法违背了接口的目的。

如果它不是一个界面,而是一个类,那就有意义了:

class A {
    virtual void foo() = 0;

    void bar() {
        foo();
    }
};

class B : private A {
    virtual void foo() {

    }
};