为什么多态派生类不能嵌套在基类中?

Mat*_*att 1 c++ polymorphism inheritance inner-classes

例如,我试图做这样的事情:

class Animal {
public:
    virtual const char *says() const = 0;

    static Animal *makeLion() { return new Lion(); }
    static Animal *makeTiger() { return new Tiger(); }
    static Animal *makePig() { return new Pig(); }

private:
    class Lion : public Animal { // error: invalid use of incomplete type ‘class Animal’
    public:
        virtual const char *says() const
        {
            return "roar";
        }
    };

    class Tiger : public Animal { // error: invalid use of incomplete type ‘class Animal’
    public:
        virtual const char *says() const
        {
            return "meow";
        }
    };

    class Pig : public Animal { // error: invalid use of incomplete type ‘class Animal’
    public:
        virtual const char *says() const
        {
            return "That\'s all Folks!";
        }
    };
};
Run Code Online (Sandbox Code Playgroud)

编译器抱怨这Animal是一个不完整的类型.但是为什么是Animal一个不完整的类型,如果内部类定义不需要定义外部类本身(因为内部类类型的非静态变量是由外部类中的值声明的)?

有没有办法绕过这个或更好的方式来做我想做的事情?

Che*_*Alf 11

}在类定义的右大括号之前,类是不完整的.

重新"有这种方法",你可以做这样的事情:

struct A
{
    struct B;
};

struct A::B
    : A
{};
Run Code Online (Sandbox Code Playgroud)

但这不是一种常见的模式.我记不起曾经见过它.


R S*_*ahu 10

有没有办法绕过这个或更好的方式来做我想做的事情?

不要使用嵌套类.只需移出派生类Animal.


单独说明,有功能

static Animal *makeLion() { return new Lion(); }
static Animal *makeTiger() { return new Tiger(); }
static Animal *makePig() { return new Pig(); }
Run Code Online (Sandbox Code Playgroud)

in Animal是设计不佳的症状.基类应该尽可能地与从它派生的类不可知.


这是一个更清晰的界面和实现的建议:

Animal.h:

namespace AnimalsNamespace
{
   // The base class
   class Animal
   {
      public:
         virtual const char *says() const = 0;
   };


   // Functions to construct objects of various sub-types of Animal.
   // Moving these out of Animal and putting them in the namespace makes
   // Animal a little bit cleaner.

   Animal* makeLion();
   Animal* makeTiger();
   Animal* makePig();
}
Run Code Online (Sandbox Code Playgroud)

Animal.cpp:

namespace AnimalsNamespace
{
   class Lion : public Animal
   {
      public:
         virtual const char *says() const
         {
            return "roar";
         }
   };

   class Tiger : public Animal
   {
      public:
         virtual const char *says() const
         {
            return "meow";
         }
   };

   class Pig : public Animal
   {
      public:
         virtual const char *says() const
         {
            return "That\'s all Folks!";
         }
   };

   Animal* makeLion() { return new Lion(); }
   Animal* makeTiger() { return new Tiger(); }
   Animal* makePig() { return new Pig(); }
}
Run Code Online (Sandbox Code Playgroud)

  • @Matt将它们放在.cpp文件中. (3认同)