1

I'm trying to use a vector of Node nodes which was created in main. The class Node is also contained in main.cpp. I have a separate .cpp and .h file for my DFS search function (my professor requested it be structured like this). The return type for my function is going to be a vector<Node>, but the compiler can't figure out what Node is. What can I do to use Node in my DFS search function? I played around with the extern keyword, but couldn't get it to help me. For clarity, here is some sample code:

Main.cpp

#include "DFS.h"
//other include statements
using namespace std; 

 Node::Node(int id, vector<float> vec){
        this->nodeID = id;
        this->posVals = vec;  
    }
    
int Node::getNodeID(){
        return nodeID;
   }


int main(){
    vector<Node> nodeContainer;
    nodeContainer = load(); //load function reads in a file and dynamically creates nodes and
                            //pushes them to a vector that is returned to main
                 
    cout << "\n\n\n Adjacency List: \n" << endl; //I make an adjacency list of all the data
    AdjList adjList(nodeContainer);
    adjList.makeAdjList();
   

    dfsISearch(srcNode, destinationNode);  //function from DFS
}

DFS.cpp

vector<Node> dfsISearch(int src, int dest){
        vector<Node> vectorPath;
        return vectorPath;
    }

DFS.h

#ifndef DFS_H
#define DFS_H
#include <vector>
#include "Node.h"

    vector<Node> dfsISearch(int src, int dest);

#endif

Node.h

#ifndef NODE_H
#define NODE_H
#include <vector>
using namespace std;

    class Node{
private:
public:
    int nodeID;
    vector<float> posVals;
    vector<int> connections;
    vector<pair<int, float> > destNodeWeightPair;

    Node(int id, vector<float> vec);
    
    int getNodeID();

    void addConnection(int connection);

    vector<int> getConnectionsVector();

    void addWeight(pair<int, float> pair);

    bool isConnection(int destNode);

    void display();
};

#endif

To solve, I moved added a Node.h header file, but now when I try to compile main.cpp I get this error: Undefined symbols for architecture x86_64: "dfsISearch(int, int)", referenced from: _main in main-1e3844.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

  • 1
    You need to put the definition of `class Node` in DFS.h. – n. m. could be an AI Oct 07 '20 at 17:46
  • how would I go about doing that? `class Node{ // all function and member variables};` because I just did that and it says "redefinition of Node in main.cpp, previous definition in DFS.h" is that correct, and I just have to take the definition out of main now? – CrashMan123 Oct 07 '20 at 18:16
  • Yes, if you **move** the declaration of `Node` into `DFS.h` file, you would have to remove that declaration from `main.cpp` and replace it with an `#include "DFS.h"` statement. – Remy Lebeau Oct 07 '20 at 18:21
  • Now that I have done that, I'm getting this error when i try to compile main.cpp: Undefined symbols for architecture x86_64: "dfsISearch(int, int)", referenced from: _main in main-d87357.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) – CrashMan123 Oct 07 '20 at 18:31
  • why do you still have a definition in main.cpp? –  Oct 07 '20 at 18:46
  • what is the definition you are referring to? If you mean the Node::Node functions, then I put them there because I have no where else to put them – CrashMan123 Oct 07 '20 at 18:48
  • @CrashMan123 what do you mean no where else to put them? put them in the classdefinition.cpp ! –  Oct 08 '20 at 04:23
  • @CrashMan123 I don't mind if you send me your full code on my email-ID, I will check all the files and tell you the problem –  Oct 08 '20 at 04:24

2 Answers2

0

You need to create a separate file (i.e Node.hpp) with your Node class, then include it in any other file you need.

0

Header files

Your main function shouldn't hold the functions/classes but merely control them. The right way is to declare it in a header file and then #include "headerfile.h" in any other place you would like to use them.

Example:

Good practice

headerfile.h

#pragma once

class Entity
{
private:
    int num;

public:
    std::string name;
    void set_num(int);
};

extern int a;

int add(int,int);

headerfile.cpp

#include "headerfile.h"

void Entity::set_num(int n)
{
    num = n;
}

int a = 5; // Definition of a

int add(int a,int b)   // Definition of add(int,int)
{
    return a+b;
}  

main.cpp

#include "headerfile.h" // Note: do no include the cpp file, but the .h file


int main()
{
    Entity e;
    std::cout << a;
    std::cout << add(5,10);
    return 0;
}

It is not extremely straightforward, you can read more about it here

bad practice

file.cpp

class Entity{
private:
    int num;

public:
    std::string name;
    void set_num(int n)
    {
        num = n;
    }
};

int a = 5;

int add(int a,int b)
{
    return a+b;
}

and then the same but this time you #include "file.cpp"

Don't use this method. Even though it works it is a really bad way to achieve want you want to.

Why it is bad practice

  • why is the bad practice way a bad way? Is it because all that logic is included again, when all you really need is the definition of the functions and variables? – CrashMan123 Oct 07 '20 at 18:26
  • @CrashMan123 [huge thread](https://stackoverflow.com/questions/1686204/why-should-i-not-include-cpp-files-and-instead-use-a-header#:~:text=If%20you%20%23include%20a%20cpp,implementations%20of%20the%20same%20methods.) also, if you found my answer helpful i'd appreciate if you would upvote it –  Oct 07 '20 at 18:32
  • Well i havent solved my problem just yet, I made a headerfile for the `Node` class in main, and I included it in main and in DFS.cpp and DFS.h (because Node is in a function definition) but now I am getting this error when I try to compile main.cpp: Undefined symbols for architecture x86_64: "dfsISearch(int, int)", referenced from: _main in main-d87357.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) – CrashMan123 Oct 07 '20 at 18:36
  • @CrashMan123 you need **no definition in main**, only declare it in the header file, and then define it in the cpp file. –  Oct 07 '20 at 18:37