【问题标题】:Access Derived Class When Only Base Class Header is Included仅包含基类标头时访问派生类
【发布时间】:2016-07-01 17:17:46
【问题描述】:

我试图了解是否有办法为基类设置包含指令,但也能够访问在与基类不同的标头中定义的派生类。例如:

在 GenericObject.h 中:

class GenericObject { 
    /* whatever - shared properties and methods implemented in .cpp file */ 
}

在 Ball.h 中:

class Ball : public GenericObject { 
    /* whatever - implementation details are in the .cpp file */
}

现在在其他一些实现文件(我们称之为 main.cpp)中,我有 #included "GenericObject.h"。在 main.cpp 中,我希望能够访问 GenericObject 类的成员以及 Ball 类和 GenericObject 的任何其他派生类。从我目前的试验来看,如果我尝试将 Ball 标识符声明为 Ball * b; 并因此声明属于其类的任何成员,编译器将无法识别它。

这是因为我的#include'd "GenericObject.h" 文件还没有链接到有这个派生的 Ball 类供我访问吗?如果我"#include "Ball.h",我可以正确识别并使用 Ball 类,但我无法想象我应该包含 GenericObject 类的派生类的所有头文件,对吧?

如果我不得不猜测它是如何工作的,我猜想 GenericObject 类中 Ball 类的原型声明之类的东西将是朝着正确方向迈出的一步,但我不确定是否类原型甚至是一个东西。

感谢大家的阅读和任何反馈!

【问题讨论】:

  • 你需要学习translation units的概念。简化的翻译单元是单个源文件及其所有包含的头文件。如果您没有包含正确的头文件,编译器将根本不知道您在该头文件中声明和定义的符号。
  • 我提到我怀疑是这种情况,但我想确保我没有遗漏一些明显的东西或其他最佳方法。不过谢谢!

标签: c++ class inheritance


【解决方案1】:

不,您不能使用任何尚未描述的标识符。这包括任何类,无论它是否从基类派生。

在我看来你违反了Liskov。如果你收到一个引用或指向一个基的指针,那么你不应该做任何需要你知道是否有派生的事情。您应该只使用基础接口。因此,您不再需要包含未使用仅在 THEIR 接口中定义的东西的派生类的标头。

【讨论】:

  • 我想我明白了。即使我使用基类作为接口,我仍然需要为所有派生类声明头文件,对吗?如果我有 GenericObject 类的 50 个不同的派生类,我真的需要为每个派生类创建 50 个 #include 语句吗?我想这并不是我真正关心的,因为我认为使用头文件,以便在重新编译项目时,只有已更改的文件需要重新编译。如果我有所有这些包含的头文件,这会导致编译时间增加吗?
  • 你只需要包含你正在使用的接口。如果要向下转换为 50 个不同的派生类,则需要包含所有 50 个标头。如果你不是,那么你就没有。是的,包括 50 个头文件会增加编译时间。
  • 感谢您澄清这一点。为了进一步澄清,由于我对 C++ 中的接口继承仍然有些困惑,我可以只 #include 接口(GenericObject),让 Ball 类实现 GenericObject,然后不必 #include "Ball.h" 这样吗?写出来我认为这是不可能的,但我想确定一下。
  • 在这种情况下,您不必包含 Ball.h,除非您需要按名称引用 Ball。因此,您无法创建或使用该类型的值。您只能通过指针或引用访问它。
  • 再次感谢。您是否知道任何好的示例代码可以演示您和 R Sahu 先生所建议的使用指针和引用访问像 Ball 这样的实现?对于如何使用另一种方法来完成这个场景,您有什么建议吗?我知道我还没有真正发布任何来源,但我想这是 OO 程序员面临的常见困境。或者我正在与一种糟糕的编码习惯作斗争?
【解决方案2】:

我无法想象我应该包含GenericObject类的所有派生类的头文件,对吧?

如果您想访问从GenericObject 派生的任何类,而不是通过指针或引用,您将需要#include 他们的头文件。

如果你只使用指针和引用就可以了,你不需要#include 头文件,但你仍然需要转发声明它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多