基本的 C++ 继承

Basic C++ inheritance

在学校和数百个在线视频中,C++ 继承是通过单个文件教授的;所有 classes 都在 main 之上声明。我进行了广泛的搜索以找到继承如何与头文件一起工作的单个示例,但我很惊讶以前没有人问过这个问题。

C++ 继承如何与头文件一起工作?每个 sub class 是否需要它自己的扩展基本头文件的新头文件,或者 subclass 定义文件是否可以定义 superclass 头文件的函数?

此外,摘要 class 是否会影响上述问题?

在 C++ 中,头文件的内容由预处理器插入 #included。因此,将您正在使用的所有定义放在一个文件中与将这些定义拆分到各个头文件之间没有实质性区别。相同的规则适用 - 特别是,您需要在子 class 之前声明父 class,因此您需要在子 class 之前 #include 相关父 class class。摘要 classes 不会改变任何讨论。头文件是预处理器给我们人类的一个细节,而不是 C++ 语言理解的任何东西。

我将尝试一种非正式的回答 -- 不是那么技术性,因为我认为它适合问题的级别。

头文件一点也不神奇。您甚至可以使用“.cpp”扩展名和 #include 来命名它们。那将是一个可怕且令人困惑的约定,但您可以做到。当您执行以下操作时:

#include "foo.h"

...所有预处理器所做的就是抓取内容和 foo.h 并将其复制并粘贴到源文件中。所以对于头文件没有特殊的地位,以前没有人问过这种问题的原因可能是因为它有点奇怪。

当您尝试将所有这些代码放在一起时,重要的是编译器看到的内容以及链接器可用的内容。如果您从基 class (superclass) 继承,那么您需要确保编译器在您尝试继承时可以看到基 class 的定义它。例如:

class Sub: public Base // the compiler must be able to see the 
                       // definition of 'Base' at this point.

这是您在订单方面需要确保的。一种方法是将它们都放在同一个头文件中:

class Base {...};
class Sub: public Base {...};

...当然有必要的包括守卫(强烈推荐)。就组织而言,可能更容易且通常更清洁更像这样:

// Base.h
#ifndef BASE_H
#define BASE_H

class Base {...};

#endif

// Sub.h
#ifndef SUB_H
#define SUB_H

#include "Base.h"

class Base: public Sub {...};

#endif

这两者中的任何一个都将确保编译器在 Sub 尝试从它继承时可以看到 Base 的定义。最后但同样重要的是,抽象在这种情况下没有区别。您所要做的就是确保编译器可以通过 providing/including 以正确顺序定义这些 class 的代码在正确的时间看到它需要看到的内容。

包含定义了基础 class 的 Header 必须使给定源文件中的任何 class 能够继承基础 class。

所以我认为我们不需要为每个派生的 class 包含 header。由于问题询问继承如何与 header 文件一起工作,这里是简单的演示

文件 1:base.h

   class Shape
   {
      public:
         void setWidth(int w)
         {
            width = w;
         }
         void setHeight(int h)
         {
            height = h;
         }
      protected:
         int width;
         int height;
};

文件 2 : derived.h

#include "base.h"
// Derived class
class Rectangle: public Shape
{
   public:
       int getArea()
       { 
          return (width * height); 
       }
};

文件 3:main.cpp

#include"derived.h"
using namespace std;
int main(void)
{
    Rectangle Rect;
    Rect.setWidth(5);
    Rect.setHeight(7);

    // Print the area of the object.
    cout << "Total area: " << Rect.getArea() << endl;
    return 0;
}

输出将为 35。 希望对你有帮助。

Does each sub class need a it's own new header file that extends the base header

没有。每个子 class 不需要在单独的 header 文件中定义。他们也可以都在一个大 header 里。但将它们分开是个好主意,因为一个 subclass 的用户可能不需要所有它们的定义。

如果 扩展基数 header 你的意思是它们包括定义基数 class 的 header,那么是的,因为必须定义基础 class 才能定义继承它的 class。

or can the subclass definition file define the functions for superclass header file?

只要所有 non-inline 函数都定义在某个编译单元(.cpp 文件)中,并且没有在多个编译单元中定义这样的函数,那么一切都很好。但是为了避免混淆,我建议在它自己的单独编译单元中定义基 class 的函数。

Also, does an abstract class affect the above questions at all?

没有