有没有办法阻止在派生类中调用特定的继承函数?

时间:2015-08-18 19:50:11

标签: c++ class inheritance member virtual-functions

请考虑以下事项:

GetUpperBound(0)

有一个类作为多个其他类的公共基类。但是,让我们说一个派生类中不需要的基类成员函数之一。有没有办法明确禁止派生类中的继承函数?

现实地,我们可以讨论一个拥有1000个成员的基类,并且我们想要继承它们中的999个,所以简单地放弃继承并且只是复制所有代码将导致非常糟糕的代码可维护性。

在虚拟基类中创建该函数,并在class base { // base class public: void doBaseStuff() { /* do something basic */ } private: int someDataMember; }; class derived : public base { // this class inherits 'doBaseStuff()' as well as 'someDataMember' public: void doDerivedStuff() { /* do something in addition that only this type of derived class can do */ } }; class specialDerived : public base { // say 'doBaseStuff()' doesn't make sense in the context of this class! // we do not want to inherit that function here // is there a way to prevent instances of this class from calling it? // we still want 'someDataMember', so we must derive from the base class public: void doSpecialStuff() { /* do something in addition that only this special derived class can do */ } }; 类中提供它的虚拟实现将起作用。但是,如果该函数具有实际的返回类型,而不是specialDerived,该怎么办?然后void类必须提供返回某些内容的实现。然后调用者可以假设他们获得的值是有意义的,当它真的没有时,这是一个问题。

简单地在specialDerived中使用单个specialDerived实现虚拟函数可能是一个解决方案,只要存在一些明确说明在此特定派生类型的对象上调用此函数的文档没有意义,这个操作会抛出。我认为这是一种可能的解决方案,但我不确定这是否是最佳方式。

2 个答案:

答案 0 :(得分:1)

我假设您只是想确保该方法不会被意外调用,即调用时的编译错误是完美的。

您只需使用已删除的定义覆盖doBaseStuff中的specialDerived

class specialDerived : public base {
  void doBaseStuff() = delete;

public:
  void doSpecialStuff() {
      /* do something in addition that only this special derived class can do */
  }
};

这会阻止任何人使用specialDerived::doBaseStuff。仍然可以将对specialDerived的引用转换为对base的引用,并在结果上调用doBaseStuff,但在不制作doBaseStuff的情况下无法避免virtual

答案 1 :(得分:1)

  1. doBaseStuff
  2. 中声明base受保护
  3. base2中获取一个新的base课程,该课程只会doBaseStuff公开
  4. base2而不是base
  5. 派生999个班级
  6. base
  7. 派生一个班级

    像这样:

    class base {
    protected:
        void doBaseStuff() {
            /* do something basic */
        }
    private:
        int someDataMember;
    };
    
    class base2 : public base {
    public:
        using base::doBaseStuff; // make it public
    };
    
    class derived : public base2 {
       // ...
    };
    
    class specialDerived : public base {
       // doBaseStuff not public here since we're derived only from base (and not base2) and didn't make it public ourself
    };