在继承中实现虚拟函数

Implementing virtual functions in inheritance

本文关键字:虚拟 函数 实现 继承      更新时间:2023-10-16

我有一个关于c++中类的练习,在这个练习中我创建了一个类似于so(File.h)的文件系统

class File {
   public:
   virtual string getName();
   virtual void print() const=0;
   virtual bool operator==(const File& file) const=0;
}

然后,我在File.cpp中实现了getName,并创建了TextFile.h

class TextFile : public File {
   public:
   void print() const;
   void operator==(const TextFile& textFile) const;
   private:
   string text_;

TextFile.cpp 中的实现

void TextFile :: print() const {
   cout << text_ << endl;
}
bool TextFile :: operator==(const TextFile& textFile) const {
   return true; //just for compiling
}

编译时我们得到:

$ g++ -Wall -g File.cpp TextFile.cpp -o  RunMe
TextFile.cpp: In function ‘int main()’:
TextFile.cpp:8:11: error: cannot declare variable ‘Ilan’ to be of abstract type ‘TextFile’
  TextFile Ilan("Ilan", NULL, "Blah n NewLine");
           ^
In file included from TextFile.cpp:1:0:
TextFile.h:8:7: note:   because the following virtual functions are pure within ‘TextFile’:
 class TextFile: public File
       ^
In file included from TextFile.h:4:0,
                 from TextFile.cpp:1:
File.h:57:18: note:     virtual bool File::operator==(const File&) const
     virtual bool operator==(const File& file) const = 0;

我可能不知道如何很好地处理继承和运算符函数(看到print函数很好地工作),但在浏览课程材料时,我找不到问题。

过载与超控。。。

File中,您声明了虚拟函数

bool operator==(const File & file) const

纯净。(= 0)。所以File是一个抽象类,它的子类也不被重写。

TextFile中,您使用同名函数(operator==)重载

bool operator==(const TextFile & textFile) const 

但您不能覆盖,因为参数的类型不同。因此TextFile是一个抽象类,因为

bool TextFile::operator==(const File & file) const

仍然没有定义。

EDIT:如果使用C++11关键字"override",编译器可以检测到此类问题。在TextFile.h:中

class TextFile :  public File 
{
   ...
   void print()            const override;
   bool operator== (.....) const override; 
   ...
 }

一条消息会告诉函数是否真的没有在应该覆盖的时候覆盖。

编译器告诉您,它不能将Ilan声明为"Textfile"类型,因为"虚拟函数是纯的",然后为您提供纯虚拟函数的名称。

在C++中,纯虚拟函数是指已经被声明为虚拟的函数,并且没有为其定义实现。如果一个类具有任何纯虚拟函数,那么它就是一个虚拟类,并且不能创建该类的实例。这对于创建抽象接口很有用,这就是您对父类所做的。

在您的案例中,您已经在TextFile声明中指定==运算符是类运算符,但您已经在全局命名空间中定义了==运算符。要更正此问题,您可以在全局命名空间中声明==运算符,或将其定义为TextFile的一部分(正如Ed Heal建议的那样),但您应该更喜欢前者,原因如下:运算符重载:成员函数与非成员函数?

bool operator==(const &TextFile textFile) const {

不正确-应该是

  bool TextFile::operator==(const TextFile& textFile) const {

因为它需要定义。

File.h

class File {
   public:
   virtual string getName() const=0;
   virtual void print() const=0;
};

文本文件.h

class TextFile : public File {
   public:
   string getName() const;
   void print() const;
   bool operator==(const TextFile& textFile) const;
   private:
   string text_;
};

文本文件.cpp

string TextFile ::getName() const{
   return text_;
}
void TextFile :: print() const {
   cout << text_ << endl;
}
bool TextFile :: operator==(const TextFile& textFile) const {
   return text_==textFile.text_; 
}