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

发布于 2024-11-19 14:29:32 字数 296 浏览 3 评论 0原文

假设这个构造

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


class APoliticallyCorrectImplementationOfFooRelatedThings : private InterfaceForFoo
{

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

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

suppose this construct

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


class APoliticallyCorrectImplementationOfFooRelatedThings : private InterfaceForFoo
{

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

Now, i'm wondering if inheriting privately from an interface in this way do have any useful scenarios.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

姜生凉生 2024-11-26 14:29:32

呵呵,这里的每个人都说“不”。我说“是的,这确实有道理。”

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 的实例强制转换为 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

Huh, everyone here says "no". I say "yes, it does make sense."

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);
    }
};

Making inheritance private doesn't mean that you can't access the members of VirtualBase from outside the class, it only means that you can't access those members through a reference to Concrete. However, Concrete and its friends can cast instances of Concrete to VirtualBase, and then anybody can access public members. Simply,

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
漫雪独思 2024-11-26 14:29:32

问题是为什么基类只有纯虚方法很重要?

这两件事几乎无关。私有意味着它是类的实现细节,而不是公共接口的一部分,但您可能希望将接口实现为实现细节。假设您编写了一个类,并且决定通过需要您实现接口的库来实现功能。这是一个实现细节,没有必要仅仅因为接口只有纯虚函数而将继承设为公共。

The question is why should it matter that the base class has only pure virtual methods?

The two things are almost unrelated. Private means that it is an implementation detail of your class, and not part of the public interface, but you might want to implement an interface as an implementation detail. Consider that you write a class, and that you decide to implement the functionality by means of a library that requires you to implement an interface. That is an implementation detail, there is no need to make the inheritance public just because the interface has only pure virtual functions.

三五鸿雁 2024-11-26 14:29:32

在面向对象方面,抽象没有这种私有继承的用例。

但是,如果您想强制子类必须派生某些方法,那么您可以使用它。例如:

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 最终版)。

On object oriented aspect there is no use case for such private inheritance for an abstract class.

However, if you want to mandate that you child class must derive certain methods then you can use this. For example:

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

So, it just helps to maintain the personal coding discipline. Message with this example is that, inheritance is not just meant for object oriented purpose. You can even use inheritance for stopping inheritance chain (something like Java final).

小…红帽 2024-11-26 14:29:32

呃?不,这绝对没有意义,因为您提供接口的原因是您希望其他人通过该接口使用您的类。如果他们不知道你实施了它,那将如何运作?

#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*

Eh? No, that makes absolutely no sense, since the reason you provide an interface is that you want other to use your class through that interface. How would that work if they don't know you implement it?

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

The above example doesn't work because the outside world doesn't know that DoesFoo is a Fooable, as such you cannot new an instance of it and assign it to a Fooable*.

烈酒灼喉 2024-11-26 14:29:32

并不真地。如果你需要一个函数,你就实现它。强制一个不能被其他类使用的函数是没有意义的。

我不知道为什么要从接口私有继承;这违背了接口的目的。

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

class A {
    virtual void foo() = 0;

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

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

    }
};

Not really. If you need a function, you implement it. It makes no sense to force a function that cannot be used by other classes.

Why you would inherit privately from an interface, I don't know; that kind of defeats the purpose of interfaces.

If it's not an interface, but instead a class, it makes sense:

class A {
    virtual void foo() = 0;

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

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

    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文