基本的C++继承

4

在学校里和成百上千的在线视频中,C++继承是通过单个文件进行教授的;所有的类都在main函数之前声明。我搜索了很多地方,想找到一个关于如何与头文件一起使用继承的例子,但令我惊讶的是,似乎没有人曾经提过这个问题。

C++继承如何与头文件一起使用?每个子类是否需要自己的新头文件来扩展基础头文件,还是子类定义文件可以为超类头文件定义函数?

此外,抽象类是否会对上述问题产生影响?

4个回答

5
在C++中,头文件的内容是由预处理器插入到它们所在的#include处的。因此,在单个文件中放置所有你正在使用的定义和在多个头文件之间拆分这些定义之间没有实质性的区别。同样的规则适用-特别是,在子类之前声明父类,因此需要在子类之前#include相关的父类。抽象类不会改变该讨论的任何内容。头文件是预处理器为我们人类提供的一种便利,而不是C++语言理解的任何东西。

1
@AndrewNo,从来不包括.cpp文件是一种惯例,你是正确的。然而,声明类在头文件中也是一种惯例。你可以在相应的.cpp文件中定义方法,但你也可以直接在头文件中定义它们。如果你在ParentClass.h中定义了ParentClass,在ChildClass.h中定义了ChildClass,在ParentClass.cpp和ChildClass.cpp中分别实现了它们的方法,并且在main.cpp中编写了主程序,有很多方法可以组织你的#include,以使一切正常。你可以这样做,使头文件不包含任何内容,例如: - Patrick87
我回复了一条拼写错误很严重的评论,这是那条评论:“我总是被告知不要包含cpp文件,只包含头文件。如果这是真的,子类是否需要一个单独的头文件?如果是这样的话,难道不应该将单独的头文件扩展到基础头文件中吗?” - Andrew No

4
我将尝试给出一种非正式的答案--不太技术化,因为我认为它适合这个问题的级别。
头文件并没有什么神奇的地方。你甚至可以用“.cpp”扩展名命名它们,并包含它们。那将是一种可怕和混乱的惯例,但你可以做到。当你这样做时:
#include "foo.h"
所有预处理器所做的就是获取内容和foo.h,然后将其复制并粘贴到源文件中。所以对于头文件来说,没有特殊的地位,可能之前没有人问过这样的问题,因为这是一个有些奇怪的问题。
重要的是要考虑编译器在组合所有代码时所看到的内容和链接器所拥有的内容。如果你要从基类(超类)继承,那么你需要确保编译器在你尝试从基类继承时能够看到基类的定义。例如:
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的定义可见。最后,抽象在这种情况下没有影响。你需要做的就是确保编译器在正确的时间提供/包含定义这些类的代码,以便能够看到它所需的内容。


1

每个子类都需要一个扩展基础头文件的新头文件吗?

不需要。每个子类不需要在单独的头文件中定义。它们也可以在一个大的头文件中定义。但是最好将它们分开,因为一个子类的用户可能不需要所有子类的定义。

如果您所说的 扩展基础头文件 是指包含定义基类的头文件,那么是的,因为必须定义基类才能定义继承它的类。

子类定义文件是否可以为超类头文件定义函数?

只要所有非内联函数都在某个编译单元(.cpp文件)中定义,并且没有这样的函数在多个编译单元中定义,那么就没问题了。但为避免混淆,我建议将基类的函数定义在它自己的单独编译单元中。

抽象类是否对上述问题有影响?

没有。


0
包括定义基类的头文件,可以使给定源文件中的任何类都能继承基类。
因此我认为我们不需要为每个派生类包含头文件。由于问题要求解释继承如何与头文件一起工作,这里是一个简单的演示:
文件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。 希望它有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接