-1

I am trying to implement Heap ADT in C++. I am currently facing a problem in the my overloaded operator<<. I saw many solutions but non worked for me: first solution || Here is the second one

Here is the hpp file:

#ifndef Heap_hpp
#define Heap_hpp

#include <stdio.h>
#include <vector>
#include <string>
#include <iostream>


using namespace std;
typedef int elementType;

class Heap{
private:
    vector<elementType> myVecrtor;
    int mySize = 1; //The minimum size is 1 since 
                   //the first element is a dummy.

public:
    Heap();
    //some functions...
    //My problem is in this function
    friend ostream& operator<<(ostream &out, Heap &h);
    void perculateDown(int root);
    void perculateUp();
};

#endif /* Heap_hpp */

Here is the cpp file:

#include "Heap.hpp"
using namespace std;

Heap::Heap(){
}
ostream& Heap::operator<<(ostream &out, Heap &h){//it is giving me the error here
    out<<"\t\tHeap:";
    for(int i = 0; i < mySize; i++){
        out<<myVecrtor.at(i);//this is not what i actualy want to display, just a demo
    }
    return out;
}

I need to mention that i tried it not as a friend and it gave me the same error And when initializing the function inside the cpp file like this:

ostream& operator<<(ostream &out, Heap &h)

the error was gone but i wasn't able to use any member. Any help other than the solutions I have mentioned would be appreciated.

Also removing the qualification (Heap::) prevents me from using any member of my class for some reason. error: Use of undeclared identifier 'mySize'

image showing the error I tried using h.mySize, it gave me: 'mySize' is a private member of 'Heap' private member error photo

  • 2
    The `Heap::` in the _definition_ of the operator is wrong. (Just remove it.) The `friend` declaration refers to a plain function but not a member function (even although it appears inside a class definition). FYI: [friend declaration](https://en.cppreference.com/w/cpp/language/friend) – Scheff's Cat Apr 14 '22 at 16:15
  • 2
    O.T. `using namespace std;` is a bad idea - especially in a header. [Why is "using namespace std;" considered bad practice?](https://stackoverflow.com/q/1452721/7478597) – Scheff's Cat Apr 14 '22 at 16:21
  • 2
    O.T. An formatted stream output operator (`operator<<()`) should have a const reference (or value) as 2nd parameter to emphasize that it won't change that instance - i.e. `std::ostream& operator<<(std::ostream&, const Heap&)`. – Scheff's Cat Apr 14 '22 at 16:24
  • True I should add const. – Youssof. K. Apr 14 '22 at 18:33
  • I am aware that the use of namespace std is bad practice but i have not found any alternatives other than writing std::. – Youssof. K. Apr 14 '22 at 18:35
  • What's wrong with `std::`? These are 5 characters only. Once you get used to it it's not that annoying you might be afraid (at least, according to my own experience). IMHO, it emphasizes things of the standard library in your code which is not the worst thing. – Scheff's Cat Apr 15 '22 at 11:42

1 Answers1

1

The problem is that you've defined the overloaded operator<< as a member function of class Heap instead of defining it as a non-member function.

To solve this you should remove the Heap qualification(Heap::) while defining the overloaded operator<< as shown below:

//------v-----------------------------------> removed Heap:: from here
std::ostream& operator<<(std::ostream &out, Heap &h){
    for(int i = 0; i < h.mySize; i++){
//---------------------^^-------------------->added h. here
        out<<h.myVecrtor.at(i); 
//-----------^^------------------------------>added h. here
    } 
    return out;
}

Additionally, when implementing the overloaded operator<<, we make the second parameter as an lvalue reference to const since operator<< doesn't change the state of the object. So after modification the code would look something like:

class Heap{
//other code as before
public:
//------------------------------------------vvvvv------------>added const here
    friend std::ostream& operator<<(std::ostream &out,const Heap &h);
   
};
//------v---------------------------------------------> removed Heap:: from here
std::ostream& operator<<(std::ostream &out,const Heap &h){
//-------------------------------^^^^^---------------->added const here
    for(int i = 0; i < h.mySize; i++){
        out<<h.myVecrtor.at(i);//this is not what i actualy want to display, just a demo
    }
    return out;
}

Demo

Important Note

Note that you should not use using namespace std; inside header files like you've done in your example. You can refer to Why is "using namespace std;" considered bad practice?.

Also, note that since operator<< is a non-member function, so we have to use h.mySize and h.myVecrtor.at(i) instead of just using mySize and myVecrtor.at(i).

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56
Jason
  • 36,170
  • 5
  • 26
  • 60
  • Yes I mentioned later on that I tried removing Heap qualification but this prevents me from using the members – Youssof. K. Apr 14 '22 at 18:31
  • Here is a [working demo](https://onlinegdb.com/RO2uteQHF). Note that you should avoid using `using namespace std;`. See [Why is "using namespace std;" considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – Jason Apr 14 '22 at 18:40
  • I appreciate the help, but my problem is when i am trying to use members of my class like mySize and myVector and any other functions. The error: Use of undeclared identifier 'mySize'. – Youssof. K. Apr 14 '22 at 18:43
  • @Youssof.K. That is because you've to use `h.mySize` and `h.myVecrtor.at(i)` . See [demo](https://onlinegdb.com/ZPtZhTNJM). That is you have to use `h.` since `operator<<` is a non-member function. Note in my edited answer, i have used `h.mySize` and `h.myVecrtor.at(i)` instead of just using `mySize` and `myVecrtor.at(i)`. – Jason Apr 14 '22 at 18:47
  • i tried and gave me i can't use it since it's a private member, the mySize. – Youssof. K. Apr 14 '22 at 18:53
  • @Youssof.K. That overloaded `operator<<` is a friend function, so you'll be able to use the private members freely without any error. Make sure that you have a friend declaration for that overloaded `operator<<` inside the class. In [this demo](https://onlinegdb.com/ZPtZhTNJM), i am using `mySize` member even though it is private. – Jason Apr 14 '22 at 18:54
  • @Youssof.K. Please don't update the original question by taking and applying suggestion from answers. Instead you can post the error that you're getting here as a comment. Otherwise that makes the answer obsolete and wastes people's time. – Jason Apr 14 '22 at 18:59
  • I am using the friend declaration. But for some reason it is not working. – Youssof. K. Apr 14 '22 at 18:59
  • You are right I am sorry. But I added the photo showing the errors. – Youssof. K. Apr 14 '22 at 19:00
  • @Youssof.K. Can you post here in the comments a link to the screenshot of how your class definition(header file) looks like? Also, use `std::ostream` instead of just `ostream` in both header as well as source file. I am sure that will make the error go away. In the second image that you postead, i saw that you were still using `ostream`. Instead use `std::ostream` in both the header file as well as source file. Also, remove the `using namespace std;` from both the files. That is why i provide a [working demo](https://onlinegdb.com/ZPtZhTNJM). – Jason Apr 14 '22 at 19:00
  • this is my class definition is like in my .h file [enter image description here][1] [1]: https://i.stack.imgur.com/Evw7D.png – Youssof. K. Apr 14 '22 at 19:07
  • @Youssof.K. In this image i can see that you forgot to add `std::` to the first parameter named `out` of the overloaded `operator<<` . Change all the occurrences of `ostream` to `std::ostream` not just one. Do this in all of the files(all header and source files) – Jason Apr 14 '22 at 19:10
  • Still, I think my editor is not debugging correctly. [cpp][1] [hpp][2] [1]: https://i.stack.imgur.com/4OvW1.png [2]: https://i.stack.imgur.com/KpG00.png – Youssof. K. Apr 14 '22 at 19:18
  • @Youssof.K. You forgot to make the second parameter `const` in the declaration inside class definition. Add a `const` in the 2nd parameter in the declaration inside class definition and your program will work. – Jason Apr 14 '22 at 19:20
  • oh wow. It worked. So stupid of me. Sorry for bothering you. – Youssof. K. Apr 14 '22 at 19:21
  • such a silly mistake... – Youssof. K. Apr 14 '22 at 19:21