例如,我试图做这样的事情:
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!";
}
};
};
编译器抱怨Animal
是一个不完整的类型。但是为什么Animal
是一个不完整的类型,如果内部类定义不需要定义外部类本身(因为内部类类型的非静态变量是由外部类中的值声明的)?
有没有办法解决这个或更好的方法来做我想做的事情?
答案 0 :(得分:11)
在类定义的右大括号}
之前,类尚未完成。
Re“有解决方法”,你可以这样做:
struct A
{
struct B;
};
struct A::B
: A
{};
但它并不常见。我不记得曾见过它。
答案 1 :(得分:10)
有没有办法绕过这个或更好的方式去做我想做的事情?
不要使用嵌套类。只需将派生类移出Animal
。
单独注意,有功能
static Animal *makeLion() { return new Lion(); }
static Animal *makeTiger() { return new Tiger(); }
static Animal *makePig() { return new Pig(); }
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();
}
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(); }
}
答案 2 :(得分:2)
一种可能的解决方案是将Lion,Tiger,Pig的定义放在功能范围内:
class Animal {
public:
virtual ~Animal() = default;
virtual const char *says() const = 0;
static std::unique_ptr<Animal> makeLion()
{
class Lion : public Animal
{
public:
virtual const char *says() const override
{
return "roar";
}
};
return std::make_unique<Lion>();
}
static std::unique_ptr<Animal> makeTiger() {
class Tiger : public Animal
{
public:
virtual const char *says() const override
{
return "meow";
}
};
return std::make_unique<Tiger>();
}
static std::unique_ptr<Animal> makePig() {
class Pig : public Animal
{
public:
virtual const char *says() const override
{
return "That\'s all Folks!";
}
};
return std::make_unique<Pig>();
}
};
int main() {
std::cout << Animal::makeLion()->says() << std::endl;
}
答案 3 :(得分:-1)
糟糕的设计。不应在Animal类中创建对象。考虑重新设计类:
class Animal
{
public:
virtual const char* says() const = 0;
};
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* p = new Pig;
cout << p->says() << endl;
否则,每次添加新类型时都必须添加makeXXX()函数。