-1

I have an exercise dealing with classes in c++, in which I create a file system like so (File.h)

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

Then, I implement getName in File.cpp and create TextFile.h

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

   private:
   string text_;

Implement in TextFile.cpp

void TextFile :: print() const {
   cout << text_ << endl;
}

bool TextFile :: operator==(const TextFile& textFile) const {
   return true; //just for compiling
}

when compiling we get:

$ 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;

I probably don't know how to work well with inheritance and operator functions (seeing the print function works well), but I can't find the problem when looking through my course material.

Oded Sayar
  • 427
  • 1
  • 4
  • 17

4 Answers4

1

OVERLOAD vs. OVERRIDE...

In File you declare the virtual function

bool operator==(const File & file) const

as pure. (= 0). So File is an abstract class, and so are its subclasses where it is not overridden.

In TextFile, you overload it with a function with the same name (operator==)

bool operator==(const TextFile & textFile) const 

but you don't override it, because the parameters are not the same type. Consequently TextFile is an abstract class because

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

is still not defined.

EDIT: the compiler can detect such problems if you use the C++11 keyword "override". In TextFile.h :

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

a message will tell if the functions actually don't override when they are supposed to do.

Michel Billaud
  • 1,758
  • 11
  • 14
  • So how do I make it compile? I want the function to work only for `TextFile` class. Thanks – Oded Sayar Jun 28 '15 at 12:47
  • Could you please be more specific ? What do you mean by "work only for TextFile" ? If so, why declare it in File as a virtual function ? – Michel Billaud Jun 28 '15 at 12:53
  • Frankly It's declared there bc it's how I got `File.h` and I was asked not to change it. I can Implement it on 'File.cpp', but it would be pointless for it should compare the `string text_` field, which is only in `TextFile` – Oded Sayar Jun 28 '15 at 12:57
  • In this case, change the parameter type in TextFile::operator== to const File &. And use the C++11 keyword "override", so the compiler will check for you. – Michel Billaud Jun 28 '15 at 12:59
  • Thanks, now it works. Won't it cause problem in the future (for calling a parent class from within the inheriting one, or something like that)? – Oded Sayar Jun 28 '15 at 13:03
  • Life is an endless cause of problems. Especially life with the C++ language. – Michel Billaud Jun 28 '15 at 13:08
1

The compiler is telling you that it can't declare Ilan to be of type "Textfile", because a "virtual function is pure", and then gives you the name of the pure virtual function.

In C++ a pure virtual function is one which has been declared virtual, and for which no implementation is defined. If a class has any pure virtual functions, it is a virtual class, and you cannot create an instance of that class. This is useful for creating abstract interfaces, which is what you have done with your parent class.

In your case, you have specified that the == operator is a class operator in the TextFile declaration, but you have defined the == operator in the global namespace. To correct this, you can either declare the == operator in the global namespace, or define it as part of TextFile (as Ed Heal suggested), but you should prefer the former for the reasons discussed here: Operator overloading : member function vs. non-member function?

Community
  • 1
  • 1
Spacemoose
  • 3,856
  • 1
  • 27
  • 48
  • Thanks for the info, I used Michael Billaud's answer for now and it works great, but I will read your link later on, it looks good for better understanding – Oded Sayar Jun 28 '15 at 13:10
0

The line

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

is incorrect - should be

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

As it needs to be defined.

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
0

File.h

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

TextFile.h

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

   private:
   string text_;
};

TextFile.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_; 
}
kiviak
  • 1,083
  • 9
  • 10