1

抽象类具有内部虚函数。抽象类可以有内部虚拟类稍后实现吗?

我尝试了以下方法:

#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()'的无效抽象返回类型

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

4

3 回答 3

2

在目前的代码中,class C1::Childclass C2::Child没有继承关系。因此,它们是完全不相关的类。即使您将它们与继承联系起来,也getChild()无法返回Child(值)。它可以返回Child&(reference) 或Child*(pointer) 以形成具有协方差virtual的有效方法。参考:C++虚函数返回类型

override使用C++11 中可用的说明符很容易捕获此类错误。

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

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

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

“child是一个抽象类,后面会实现”

virtual方法一样,类没有这样的运行时关系。
在类的上下文中“稍后实现”​​的最佳含义是——在封闭类的主体之外实现它,例如:

class Outer { public: class Inner; };
// ...
class Outer::Inner { ... };
于 2017-01-03T09:37:09.843 回答
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可以简单的看成是一个classinside namespace C1,sinceclass也是一种namespace有一定限制的。

于 2017-01-03T10:05:45.237 回答
0

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

Child是一个抽象类,后面会实现,希望实现的Child可以用来定义一个函数。

纯虚拟方法(virtual int getint() = 0;在您的示例中)并不意味着“稍后”实现。它意味着由派生类中的覆盖方法实现。

例如,如果你有

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; }
};
于 2017-01-03T09:57:41.420 回答