lundi 23 septembre 2019

How do I overload the '==' operator between two different classes?

I've read the tutorials on how to use C++ operator overloading but I'm still confused.

I have a node struct which is wrapped by Node (a wrapper class) according to the Geeks for Geeks tutorial it seemed that if I wanted to be able to say n == N then I'd have to define a global operator, and make it a friend of the class? I did that, and it still isn't working, I get this error

g++    -c -o main.o main.cpp
In file included from main.cpp:3:0:
node.hpp:25:29: warning: inline function ‘virtual bool Node::operator==(const Node&)’ used but never defined
         virtual inline bool operator==(const Node &n);
                             ^~~~~~~~
node.hpp:27:28: warning: inline function ‘bool operator==(node, const Node&)’ used but never defined
         friend inline bool operator==(const node n, const Node &nt);
                            ^~~~~~~~
node.hpp:26:29: warning: inline function ‘virtual bool Node::operator==(node)’ used but never defined
         virtual inline bool operator==(const node n);
                             ^~~~~~~~
g++ -o edit main.o node.o
main.o: In function `main':
main.cpp:(.text+0x128): undefined reference to `operator==(_node_str*, Node const&)'
collect2: error: ld returned 1 exit status
Makefile:5: recipe for target 'edit' failed
make: *** [edit] Error 1

Which makes no sense to me, because I defined the == function in node.cpp so it's not undefined as far as I know

Here's my code:

node.hpp

#pragma once

#include <iostream>

typedef unsigned long int reference_counter;

typedef struct _node_str {
    reference_counter ref_cnt;
} node_str;

typedef node_str* node;

class Node {
    private:
        friend std::ostream& operator<<(std::ostream&, const Node&);

    public:
        node n;

        Node();
        Node(node n);
        virtual ~Node();

        virtual inline node operator->();
        virtual inline bool operator==(const Node &n);
        virtual inline bool operator==(const node n);
        friend inline bool operator==(const node n, const Node &nt);
};

node node_create();

And then in node.cpp

#include "node.hpp"

node node_create()
{
    node temp = (node)malloc(sizeof(node_str));
    temp->ref_cnt = 0;
    return temp;
}

// Node class definitions

Node::Node()
{
    this->n = nullptr;
}

Node::Node(node n)
{
    this->n = n;
    this->n->ref_cnt++;
}

Node::~Node()
{
    this->n->ref_cnt--;
    // TODO possibly check for and delete node upon count reaching 0
}

node Node::operator->()
{
    return this->n;
}

inline bool Node::operator==(const Node &n)
{
    return this->n == n.n;
}

inline bool Node::operator==(const node n)
{
    return this->n == n;
}

inline bool operator==(const node n,const Node &nt)
{
    return n == nt.n;
}

std::ostream& operator<<(std::ostream &strm, const Node &a)
{
    return strm << "Node Wrapper { " << a.n << ", Count: " << a.n->ref_cnt << " }";
}

And then a simple test main.cpp to use the equivalences.

#include <iostream>

#include "node.hpp"

using namespace std;

int main()
{
    cout << "Hello World!" << endl;
    node a = node_create();
    node b = node_create();
    Node A = Node(a);
    Node B = Node(b);
    cout << A << endl << B << endl;
    cout << ((A == B) ? "A == B" : "A != B") << endl;
    cout << ((a == A) ? "a == A" : "a != A") << endl;
    cout << ((A == a) ? "A == a" : "A != a") << endl;
    cout << A << endl;
}

And the makefile to wrap it all together

CC = g++
objects = main.o node.o

edit : $(objects)
    $(CC) -o edit $(objects)

main.o : main.cpp node.hpp

node.o : node.cpp node.hpp

.PHONY : clean
clean :
    rm edit $(objects)

Would anybody be able to help me understand what I'm doing wrong here?

Aucun commentaire:

Enregistrer un commentaire