0

everyone, my first post here, if my style annoys your please let me know I am looking to learn how to post here. I hope someone could help me with this LNK2019 Error

I got two source files, battleship.cpp and tester.cpp, the main() function is inside Leetcode.cpp the program will not compile and give error LNK1120 and LNK2019 while if I put the Solution class function definition in the header file battleship.h the program actually compile(and so far works well for the prototype) -- still, I am not sure if this is a good practice as these functions are not template functions and I can not justify putting them in the .h file

Error Message:

Severity    Code    Description Project File    Line    Suppression State
Error   LNK2019 unresolved external symbol "public: int __thiscall tom::Solution::boardPrinter(class std::vector<class std::vector<char,class std::allocator<char> >,class std::allocator<class std::vector<char,class std::allocator<char> > > > &)" (?boardPrinter@Solution@tom@@QAEHAAV?$vector@V?$vector@DV?$allocator@D@std@@@std@@V?$allocator@V?$vector@DV?$allocator@D@std@@@std@@@2@@std@@@Z) referenced in function "int __cdecl tom::battleshipTester(void)" (?battleshipTester@tom@@YAHXZ)  Leetcode    C:\Users\Shin\documents\visual studio 2015\Projects\Leetcode\Leetcode\tester.obj    1   

and code for battleship.cpp

#include "stdafx.h"


namespace tom{
    class Solution{
    public:
        int countBattleships(std::vector<std::vector<char>>& board) {
            return 0;
        }

        int boardPrinter(std::vector<std::vector<char>>& board)
        {   
            return 0;
        }

        int Solution::simpleBoardBuilder(std::vector<std::vector<char>>& board)
        {
            return 0;
        }
    };
}

and code for battleship.h

#pragma once
#include "stdafx.h"


namespace tom {
    class Solution {
    public:
        int countBattleships(std::vector<std::vector<char>>& board);
        int boardPrinter(std::vector<std::vector<char>>& board);
        int simpleBoardBuilder(std::vector<std::vector<char>>& board);
    };
}

code for tester.cpp

#include "stdafx.h"
#include "battleship.h"

namespace tom {
    int battleshipTester(void)
    {
        //called in main function
        //call countBattleships
        std::vector<std::vector<char>> board;
        Solution baseline;
        baseline.countBattleships(board);
        baseline.boardPrinter(board);
        baseline.simpleBoardBuilder(board);
        return 0;
    }
}

code for tester.h

#pragma once
#include "stdafx.h"

namespace tom {
    int battleshipTester(void);
    //int simple


}

code for Leetcode.cpp also where main function is

// Leetcode.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "tester.h"

int main()
{   
    tom::battleshipTester();
    return 0;
}
petergx
  • 45
  • 6
  • This is undefined behavior. The header file defines a class of a given name. The cpp file defines another class, with the same name. – Sam Varshavchik Jan 21 '17 at 00:33
  • I find it a bit odd that your `battleship.cpp` does not include `battleship.h`. Don't you? – WhozCraig Jan 21 '17 at 00:33
  • Link library issues are related to libraries not being linked to the project, are you linking the library to the project Leetcode.cpp resides in? – Abhinav Jan 21 '17 at 00:34
  • @SamVarshavchik @WhozCraig both of you are right, if I include `battleship.h` in the `battleship.cpp` file the console will say `tom::Solution: class type definition` that's why I remove it, but the truth is that I am also not sure what I should include a `.cpp` file's header in itself? I mean usually I do that but I can't tell why, could you tell me? – petergx Jan 21 '17 at 00:42
  • @SamVarshavchik btw, what is undefined? – petergx Jan 21 '17 at 00:43

2 Answers2

0

You have multiple problems in your code:

  1. Battleship.h is not included in Battleship.cpp
  2. You have defined class Solution twice
  3. You have defined class Solution in an implementation (.cpp) file
  4. You have not included tester.h in tester.cpp

The error message literally means that the compiler cannot find the definition of a function you have declared. This is true; Battleship.cpp is not included so there is not definition visible to the compiler. However, even if it had been included, you would still get errors (see numbered items above).

Nikos Kazazakis
  • 792
  • 5
  • 19
  • seems I am terribly wrong, let's change it and get back – petergx Jan 21 '17 at 00:44
  • happens to the best of us :) – Nikos Kazazakis Jan 21 '17 at 00:48
  • hi, thank you for the help! delete the duplicate definition of `Solution` class in the `battleship.cpp`, and basically I follow the tip 1,2,3 from your answer, and not the code does compile, but I am not sure why should I include `tester.cpp` in the `tester.h`, I mean, usually we just include `.h` file right? – petergx Jan 21 '17 at 00:50
  • Sorry, typo, it's the other way around, you need the .h included in the .cpp – Nikos Kazazakis Jan 21 '17 at 00:52
  • You still need to provide definitions for the Solution class methods, otherwise they are still undefined. If it still doesn't work after you implement all the changes, feel free to create another question (as it will probably look too different) :) – Nikos Kazazakis Jan 21 '17 at 00:57
0

In addition to what nikaza has answered, please refer to the following comments.

countBattleships(std::vector<std::vector<char>>& board)

is wrong. You should have an extra space after <char> like this below

countBattleships(std::vector<std::vector<char> >& board)

Only then should your code compile.

While you have used vector everywhere, I do not see any #include <vector> in any files. You may want to #include <vector> in your .h files

battleship.cpp should look something like this:

#include "battleship.h"
namespace tom{
    int Solution::countBattleships(std::vector<std::vector<char> >& board) {
        return 0;
    }

    int Solution::boardPrinter(std::vector<std::vector<char> >& board)
    {
        return 0;
    }

    int Solution::simpleBoardBuilder(std::vector<std::vector<char> >& board)
    {
        return 0;
    }
}

tester.cpp should look something like this :

#include "tester.h"
#include "battleship.h"

namespace tom {
    int battleshipTester(void)
    {
        //called in main function
        //call countBattleships
        std::vector<std::vector<char> > board;
        Solution baseline;
        baseline.countBattleships(board);
        baseline.boardPrinter(board);
        baseline.simpleBoardBuilder(board);
        return 0;
    }
}

battleship.h should look something like this:

#pragma once
#include <vector>
namespace tom {
    class Solution {
    public:
        int countBattleships(std::vector<std::vector<char> >& board);
        int boardPrinter(std::vector<std::vector<char> >& board);
        int simpleBoardBuilder(std::vector<std::vector<char> >& board);
    };
}

tester.h should look something like this:

#pragma once

namespace tom {
    int battleshipTester(void);
    //int simple
}

Finally leetcode.cpp should look like this :

#include "tester.h"

int main()
{
    tom::battleshipTester();
    return 0;
}
Community
  • 1
  • 1
Rishi
  • 1,387
  • 10
  • 14
  • thank you for the reply, after some modification my code does looks like yours right now. I included `` in the `stdafx.h` along with other library I might use, since it's just a small project I am not looking for speed up the compile time but still not sure if that's a good practice?(while it seems works fine) – petergx Jan 21 '17 at 19:11
  • More on stdafx.h here : http://stackoverflow.com/questions/2976035/purpose-of-stdafx-h. Good to know that your code compiles and executes now. – Rishi Jan 23 '17 at 06:17