0

I've done this so many times, yet the reason why Visual Studio is complaining about this escapes me.

Manipulator.cpp:

#include "Manipulator.h"

Manipulator::Manipulator() {}
Manipulator::~Manipulator() {}


void proc(std::string p, int f, std::string c)
{
    // switch-case p to c based on f: 

    return;
}

Manipulator.h: (void -proc- has a curly underscore, and that's what's driving me up the wall.)

#ifndef MANIPULATOR_H
#define MANIPULATOR_H
#include <string>

class Manipulator
{
private:

protected:

public:
    Manipulator() ;
    ~Manipulator() ;

    void proc(std::string, int, std::string);
    // function definition for 'proc' not found. 

};

#endif MANIPULATOR_H

main.cpp

#include "Manipulator.h"
...
int main() 
{
    ...
    Manipulator m; 
    ...
    m.proc(opdBMP, fxn, newBMP); 

    return 0; 
}

What is it that VS wants so that I can get a move on? It is telling me that there are two linker errors: LNK2019 and LNK1120 (unresolved external). (I used to keep track of these kinds of errors but lost the file as a log with these.)

Jason
  • 36,170
  • 5
  • 26
  • 60
  • Why are you including the header file in itself? Or do you have your header and cpp file swapped? – perivesta Dec 03 '21 at 09:29
  • Can you provide us the exact output of the compiler ? – tony_merguez Dec 03 '21 at 09:32
  • 3
    The compiler is correct in complaining, because the definition should be `void Manipulator::proc(std::string p, int f, std::string c)`. You just defined a free function instead of a member of Manipulator. – Botje Dec 03 '21 at 09:33
  • @tony_merguez Severity Code Description Project File Line Suppression State Error LNK2019 unresolved external symbol "public: void __thiscall Manipulator::proc(class std::basic_string,class std::allocator >,int,class std::basic_string,class std::allocator >)" (?proc@Manipulator@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H0@Z) referenced in function _main spriteMan_s1_complSym C:\Users\owner\source\repos\spriteMan_s1_complSym\main.obj 1 – AndrewGreen Dec 03 '21 at 09:34
  • That indicates you aren't linking `Manipulator.cpp` with `main.cpp`. How are you calling the linker? – Caleth Dec 03 '21 at 09:36
  • @Botje : I've just followed your lead, but it spat at me the following: ``` qualified name is not allowed in member declaration ``` – AndrewGreen Dec 03 '21 at 09:37
  • @Caleth : I have no clue how to answer your question. I'm just following everything I've "learned" from my CS135 and CS202 classes. How should I interact with the linker? – AndrewGreen Dec 03 '21 at 09:39
  • It looks like you are using Visual Studio, what does the "Solution Explorer" tab show as the files in your project? – Caleth Dec 03 '21 at 09:43

1 Answers1

4

The compiler is correct in complaining, because the definition should be

void Manipulator::proc(std::string p, int f, std::string c) {
...
}

You just defined a free function instead of a member of Manipulator.

Botje
  • 26,269
  • 3
  • 31
  • 41
  • What I have now is this: ```void Manipulator::proc(std::string p, int f, std::string c) { // switch-case p to c based on f: return; }``` : : : ```class Manipulator { private: protected: public: Manipulator() ; ~Manipulator() ; void proc(std::string, int, std::string); };``` This exercise requires an awful lot of guessing rather than following through with any kind of logic. – AndrewGreen Dec 03 '21 at 09:51
  • There is no guessing involved here, just knowing C++ and how the compiler/linker treat your code. – Botje Dec 03 '21 at 10:07
  • In .cpp I have to show ```void Manipulator::proc() {}```, whereas in .h I have to show ```void proc();```. Does that make sense to you? Do you know of a good book that sensibly explains how compiler/linker goes about my code? – AndrewGreen Dec 03 '21 at 10:24
  • Yes, that makes perfect sense. Consider the case where you have a class `Sensor` that *also* has a `proc` method. How would you define both cases if you do not have a way of distinguishing between the two names? C++ is not a language you can pick up by guessing, you need to actually study it. There's an [excellent answer](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) with C++ study material on the site. – Botje Dec 03 '21 at 10:25
  • Why would it matter what other class has a function with a similar name? It's the instantiated object within main.cpp that calls the class.function(){} vs class2.function(){} that makes the difference, no? – AndrewGreen Dec 03 '21 at 10:28
  • 1
    That is on the caller side, yes. But how do you keep the two _implementations_ separate? You cannot define `proc` twice and expect the compiler to know which is which. – Botje Dec 03 '21 at 10:28
  • I think there is too much confusion going on beyond the scope of this question and the comments coming from all parties. At any rate, why would it make sense to demand that Manilpulator.cpp has ```void Manipulator::proc(){}``` and not ```void proc(){}``` ? – AndrewGreen Dec 03 '21 at 10:37
  • Is your instructor expecting you to define you member functions outside the class definition? – Caleth Dec 03 '21 at 10:37
  • The fact that they haven't explained *how* to suggests they don't (or they are wanting you to learn it independently) – Caleth Dec 03 '21 at 10:41
  • Whoever gave your CS135 and CS202 classes. Instructor / Teacher / Professor – Caleth Dec 03 '21 at 10:42
  • @Caleth My bad. When you said "your instructor", I thought you meant a component within my hardware/software, not like a teacher/professor. At any rate, I'm still confused as to why VS would demand that I specify ```void Manipulator::proc(){}``` when I'm clearly in Manipulator.cpp. – AndrewGreen Dec 03 '21 at 10:48
  • Because the compiler does not ascribe any special meaning to "Manipulator.cpp". It could be called "banana.cpp" for all it cares. – Botje Dec 03 '21 at 10:48
  • 1
    It doesn't even need to be a file. You can type it in on a terminal for all the compiler cares – Caleth Dec 03 '21 at 10:50
  • @Botje : Hm, that's interesting. I wasn't told that. I'll keep that in mind and experiment with that a bit. – AndrewGreen Dec 03 '21 at 10:55
  • @Caleth : If it weren't a file, then how would the compiler take it into account? – AndrewGreen Dec 03 '21 at 10:55
  • The compiler is a program with a standard input stream. If can read the code to compile from that stream – Caleth Dec 03 '21 at 10:55
  • I guess what everyone is trying to say is that the Class.cpp implementation file, when including a Class.h file, still needs a specification as to what function it is specifying/implementing. – AndrewGreen Dec 03 '21 at 11:06