如何在c ++中实现内部抽象成员类?

时间:2017-01-03 09:28:57

标签: c++ abstract-class internal-class

抽象类具有内部虚函数。 抽象类是否可以在以后实现内部虚拟类?

我尝试了以下内容:

#include <bits/stdc++.h>
using namespace std;

class C1 {
    public:
        class Child {
            int tmp;
            virtual int getint() = 0;
        };
    virtual Child getChild() = 0;
};

class C2: public C1 {
    public:
        class Child {
            int getint()
            {
                return 10;
            }
        } c;
    Child getChild()
    {
        return c;
    }
};

int main() { return 0; }

Child 是一个抽象类,它将在派生类中重写。我希望已实现的 Child 可用于定义函数。

但是,我收到了一个错误:

  

成员函数'virtual C1 :: Child C1 :: getChild()'

的抽象返回类型无效

我不能在派生类中实现内部抽象类,就像实现虚函数一样吗?

3 个答案:

答案 0 :(得分:2)

在目前的代码中,class C1::Childclass C2::Child没有继承关系。因此,他们完全不相关的课程。即使您将它们与继承相关联,那么getChild()也不能返回Child(值)。它可以返回Child&(引用)或Child*(指针)以形成具有协方差的有效virtual方法。请参阅:C++ virtual function return type

使用C ++ 11中提供的override说明符可以轻松捕获此类错误。

在不知道您要实现的目标的确切上下文的情况下,可能的代码应如下所示:

class C1 {
  // ... same
  virtual Child& getChild() = 0;
  //      ^^^^^^ reference
};

class C2 : public C1 {
//         ^^^^^^ did you miss this?
public:
  class Child : public C1::Child {
  //                   ^^^^^^^^^ inheritance
    int getint() override { return 10; }
  } c;
  Child& getChild() override { return c; }
};

此外,您的以下陈述似乎令人困惑:

  

&#34; Child是一个抽象类,将在稍后实现,&#34;

virtual方法类似,这些类没有这样的运行时关系 &#34;以后实施的最佳意义&#34;在类的上下文中 - 在封闭类的主体之外实现它,例如:

class Outer { public: class Inner; };
// ...
class Outer::Inner { ... };

答案 1 :(得分:1)

理论上,Abstract Classes用于创建Interfaces。使用Interfaces,客户端需要所需的功能。通过定义/实施Interfaces,服务器可以实现客户端的功能。 Interface/Abstract Class只是客户端和服务器之间需求/协议的蓝图。可以实例化实现Interface/Abstract Class或满足功能要求的类。因此,可以有许多相同Interface/Abstract Class的实现。现在,为了在不同的时间点无缝地访问相同Interface/Abstract Class的所有这些不同实现,我们需要一种通用的方式。这种通用方式是通过pointer(*) or reference(&)到底层Interface\Abstract Class

在您的代码中C1::Child是一个Abstract Class or Interface

因此,C1::getChild()可以返回Interface/Abstract C1::Child的实现。但根据上述理论解释,它无法返回Interface/Abstract C1::Child本身的实例。因而错误。 声明C1::getChild()的正确方法是:

  • virtual C1::Child* getChild() = 0;
  • virtual C1::Child& getChild() = 0;

此外,C1::Child可以简单地视为class内的namespace C1,因为class也是一种namespace,但有一些限制。

答案 2 :(得分:0)

从你的帖子看,你似乎很困惑。我建议你重新阅读抽象类,并自己尝试一些简单的例子。

  

Child是一个抽象类,稍后将实现,我希望如此   已实现的Child可用于定义函数。

纯虚方法(在您的示例中为virtual int getint() = 0;)并不意味着实现&#34;稍后&#34;。它意味着通过派生类中的覆盖方法实现。

E.g。如果你有

class Child {
   virtual int getint() = 0;
};

你做不到

class Child {
   virtual int getint() { return 10; }
};

,也不

int Child::getint() { return 10; }

稍后。

你能做的是:

class Derived : public Child
{
   int getint() override { return 10; }
};