在 C++ 中,是否可以将类声明为从另一个类继承?

2021-12-17 00:00:00 inheritance forward-declaration c++

我知道我可以做到:

class Foo;

但是我可以转发声明一个类从另一个类继承,例如:

but can I forward declare a class as inheriting from another, like:

class Bar {};

class Foo: public Bar;

<小时>

一个示例用例是协变引用返回类型.


An example use case would be co-variant reference return types.

// somewhere.h
class RA {}
class RB : public RA {}

... 然后在另一个不包含 something.h 的标题中

... and then in another header that doesn't include somewhere.h

// other.h
class RA;

class A {
 public:
  virtual RA* Foo();  // this only needs the forward deceleration
}

class RB : public RA; // invalid but...

class B {
 public:
  virtual RB* Foo();  // 
}

编译器应该处理RB* B:Foo()声明的唯一信息是RBRA 作为公共基类.现在很明显,如果您打算对 Foo 的返回值进行任何类型的取消引用,您将需要 something.h.但是,如果某些客户端从不调用 Foo,那么他们就没有理由包含可能会显着加快编译速度的 something.h.

The only information the compiler should need to process the declaration of RB* B:Foo() is that RB has RA as a public base class. Now clearly you would need somewhere.h if you intend to do any sort of dereferencing of the return values from Foo. However, if some clients never calls Foo, then there is no reason for them to include somewhere.h which might significantly speed compilation.

推荐答案

前向声明仅在告诉编译器具有该名称的类确实存在并将在别处声明和定义时才真正有用.在编译器需要有关类的上下文信息的任何情况下,您都不能使用它,编译器也不能仅告诉它有关类的一点点信息.(通常,您只能在没有其他上下文的情况下引用该类时使用前向声明,例如作为参数或返回值.)

A forward declaration is only really useful for telling the compiler that a class with that name does exist and will be declared and defined elsewhere. You can't use it in any case where the compiler needs contextual information about the class, nor is it of any use to the compiler to tell it only a little bit about the class. (Generally, you can only use the forward declaration when referring to that class without other context, e.g. as a parameter or return value.)

因此,在随后使用 Bar 来帮助声明 Foo 的任何情况下,您都无法转发声明 Bar,并且具有包含基类的转发声明完全没有意义――那是什么?告诉你除了什么?

Thus, you can't forward declare Bar in any scenario where you then use it to help declare Foo, and it flat-out doesn't make sense to have a forward declaration that includes the base class -- what does that tell you besides nothing?

相关文章