0

I've seen many posts on LNK2005 error, but decided to ask my own anyway. Here is the error code:

1>setup_quest_tree.obj : error LNK2005: "private: void __thiscall quest_tree::enter_one(class quest_tree::quest_node * &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?enter_one@quest_tree@@AAEXAAPAVquest_node@1@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) already defined in mainFunction.obj
1>setup_quest_tree.obj : error LNK2005: "void __cdecl setup_quest_tree(void)" (?setup_quest_tree@@YAXXZ) already defined in mainFunction.obj
1>C:\Users\Timothy\Documents\Visual Studio 2008\Projects\ttbag\Debug\TTBAG.exe : fatal error LNK1169: one or more multiply defined symbols found

I'm trying to get the program to compile but am running into linker errors while doing so, probably because I've included quest_tree.h twice, but when I got rid of one of the declarations of quest_tree.h in setup_quest_tree.cpp I run into this error:

1>c:\users\timothy\documents\visual studio 2008\projects\ttbag\ttbag\setup_quest_tree.cpp(8) : error C2065: 'quest_tree' : undeclared identifier

There are many files so I am only including the ones for my project that are related to the error.

setup_quest_tree.cpp:

#ifndef SETUP_QUEST_NODES_CPP
#define SETUP_QUEST_NODES_CPP

#include <string>
#include "quest_tree.h"

void setup_quest_tree() {
    quest_tree quest_tree_obj;  //start out with two quest nodes

    std::string welcome_message = "debug-welcome message";
    quest_tree_obj.enter(welcome_message);
}

#endif

setup_quest_tree.h:

#ifndef SETUP_QUEST_TREE_H
#define SETUP_QUEST_TREE_H

#include "quest_tree.h"
#include "setup_quest_tree.cpp"

//function declarations
void setup_quest_tree (quest_tree &quest_tree_obj);

#endif /* SETUP_QUEST_TREE_H */

mainFunction.cpp (just the include statements):

#define DEBUG_LINES_ON

#include <iostream>
#include <fstream>
#include <time.h>

#include "weather.h"
#include "item.h"
#include "map.h"
#include "person.h"
#include "location.h"
#include "bag.h"
#include "equipped_items.h"
#include "global_vars.h"
#include "setup_quest_tree.h"


int main() { ...

quest_tree.h:

#ifndef QUEST_TREE_H
#define QUEST_TREE_H

#include <string>
#include <cstdlib>

class quest_tree {

private:

    // the basic node of the tree. Do way to read from file?
    class quest_node {
    private:
        quest_node *quest_nodes;    // pointer to array of quests that activate upon quest activation
    public:
        //std::string word; // we will replace this with our own data variable

        std::string note_to_player; //note that is shown upon quest activation

        /*
        quest_node(){   // default constructor
            note_to_player = "";
        }
        */
        quest_node(short int num_nodes = 2){
            quest_nodes = new quest_node[num_nodes];    // problem: not declared in quest_tree but rather in quest_node
            note_to_player = "";
        }



    friend class quest_tree;
    };

    // the top of the tree
    quest_node * root;

    // Enter a new node into the tree or sub-tree
    void enter_one(quest_node *&node, const std::string& note_to_player);

public:
    quest_tree() {root = NULL;} // constructor

    // Add a new note_to_player to our tree
    void enter(std::string& note_to_player) {
        enter_one(root, note_to_player);
    }
};


void quest_tree::enter_one(quest_node *&new_node, const std::string& note_to_player)
{
    // see if we have reached the end
    if (new_node == NULL) {
        new_node = new quest_node;

        for (short int index = 0; index < (sizeof(new_node->quest_nodes)/sizeof(new_node->quest_nodes[0])); index++) {  // initialize quest_nodes
            new_node->quest_nodes[index] = NULL;
        }
        new_node->note_to_player = note_to_player;
    }
    if (new_node->note_to_player == note_to_player)
        return;
/*
    if (new_node->note_to_player < note_to_player)
        enter_one(new_node->right, word);
    else 
        enter_one(new_node->left, word)
*/
}

#endif /* QUEST_TREE_H */
timgrindall
  • 139
  • 1
  • 6

1 Answers1

0

You have included the implementation in the setup_quest_tree.h header file

#include "setup_quest_tree.cpp"

and included it in several translation units.
To fix this, at least in setup_quest_tree.cpp just include the declarations from setup_quest_tree.h, and remove that #include "setup_quest_tree.cpp" statement from setup_quest_tree.h should fix your linker errors.

You have to provide exclusively one definition (implementation) for your class (see also this answer for "Is is a good practice to put the definition of C++ classes into the header file?").

If you put it there, just since you don't know how to add the setup_quest_tree.cpp to your program, check this Q&A please to learn more about the linking process.


Here's the relevant section from the current c++ standard

3.2 One definition rule [basic.def.odr]

1 No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.

Community
  • 1
  • 1
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190