【问题标题】:Multilevel Inheritance and Pure Virtual Functions多级继承和纯虚函数
【发布时间】:2013-07-02 14:34:50
【问题描述】:

包含纯虚函数的类不能有对象。这就是我对纯虚函数的想法。我有以下程序,它编译没有任何错误。

#include<iostream>

using namespace std;

class Father {
   public:
   virtual void foo()=0;
};

class Son:public Father {
  // Nothing here 
};

int main() {

}

这是意料之中的,因为这两个类都没有对象。但是,当我尝试对包含纯虚函数的类进行多级继承时,以下程序给了我错误。

#include<iostream>

using namespace std;

class Father {
   public:
   virtual void foo()=0;
};

class Son:public Father {
  // Nothing here
};

class Grand_Son:public Son {
    void foo() {
        cout<<"\nFunction foo From Grand_Son\n";
    }
};

int main() {
   Grand_Son x;
   x.foo();
}

错误如下所示。

In function 'int main()':|
|error: 'virtual void Grand_Son::foo()' is private|
|error: within this context|
||=== Build finished: 2 errors, 0 warnings ===|

错误是出乎意料的,因为我将 SonGrand_Son 类继承为 public

是否可以对涉及纯虚函数的类进行多级继承?

有什么建议吗?谢谢。

【问题讨论】:

  • 如果某些东西被认为是私有的,请检查它是否真的在你班级的公共部分。它在您的基类中是公开的,但在 Grand_Son 中不公开。
  • 有趣的是,当使用Father* x = new Grand_Son; x-&gt;foo(); 时,它会没事的,因为现在,foo() 是通过Father 访问的,它是公共的。这可用于强制 foo 仅通过多态性使用。

标签: c++


【解决方案1】:
class Grand_Son:public Son {
   public:
---^^^^^^^
    void foo() {
        cout<<"\nFunction foo From Grand_Son\n";
    }
};

你还没有声明foo public - 我在上面添加了它。

【讨论】:

    【解决方案2】:

    你在Grand_Son的私人部分有foo()

    c++ 中class 中的默认访问权限是private,这与您的继承方式(公共/私有/受保护/默认)无关。

    不仅如此,您实际上并没有使用此示例的任何继承特征,因为您在这里使用的是具体的子类,因此它与虚拟无关。

    class Grand_Son:public Son {
        public: <------- This will fix your compiler problem.
        void foo() {
            cout<<"\nFunction foo From Grand_Son\n";
        }
    };
    

    或者这应该可行,因为您将在基类上以多态方式使用该类,它将根据基类中的访问级别进行 v-table 查找。尽管在整个层次结构中,您都应该与您的访问级别保持一致。

    int main() {
       Father* x = new Grand_Son();
       x->foo();
    }
    

    【讨论】:

      【解决方案3】:

      您需要在 Grand_Son 中将您的 foo() 实现声明为 public

      【讨论】:

        【解决方案4】:

        这完全不相关。您必须在 Grand_Son 类中的 public: 语句之后声明您的 foo() 函数。

        默认情况下(即没有可见性限定符),类成员是私有的,因此您的编译器会告诉您不能访问成员函数,因为它具有私有可见性。

        【讨论】:

          【解决方案5】:

          基于标准的class.access.virt

          使用使用的表达式类型在调用点检查访问 表示调用 memeber 函数的对象。这 在定义它的类中访问 memeber 函数是 一般不知道。

          这意味着在您的示例中,它将使用 Grand_Son 来检查成员的可访问性。由于您没有将成员定义为公共,因此它将是私有的(默认情况下,类成员是私有的)。它与公共继承没有关系。

          并且将覆盖虚函数定义为私有对于设计目的也很有用。想想你有一个接口,它具有需要覆盖的公共虚拟功能。您可以通过将派生类成员函数实现为私有来强制调用者使用接口而不是具体类型。

          【讨论】:

            猜你喜欢
            • 2012-01-31
            • 1970-01-01
            • 2012-08-06
            • 1970-01-01
            • 2010-10-02
            • 1970-01-01
            • 2015-08-07
            • 2018-10-09
            • 1970-01-01
            相关资源
            最近更新 更多