0

I know it's a basic question, but I didn't find the answer anywhere.

Supose we have this header:

#pragma once;
#include "user.h"

class Teacher
{
public:
    float teachSkill = 0.01;
    void teach(User &user);
};

And a implementation like this:

#include "teacher.h"

class Teacher
{
public:
    float teachSkill;
    void teach(User &user)
    {
        user.knowledge += (*this).teachSkill;
    }
};

if we already declared that teachSkill property in the header, is there a way c++ compiler can understand that this property is in the header on an implementation like this:

#include "teacher.h"

class Teacher
{
public:
    void teach(User &user)
    {
        user.knowledge += (*this).teachSkill;
    }
};
  • 3
    Your implementation is redefining the `Teacher` class. At compile time, the contents of the header are essentially copy-pasted at the `#include` statement. I'm not entirely sure what your question is – Mouse Jul 31 '22 at 15:23
  • 2
    This is not how you define class methods in .cpp file, please get a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) to learn from. C++ can't be learned by trial and error. – Yksisarvinen Jul 31 '22 at 15:23
  • 1
    You have defined the class `Teacher` twice, and the definitions are different. That breaks a rule known as the "one definition rule" - and doing so causes undefined behaviour. In the implementation file, only `#include "teacher.h"` and define its member function (in a way consistent with the declaration in the header) as something like `void Teacher::teach(User user) { .....}`. If you want that function to be able to modify the object passed by the caller as `user` change both the declaration (in the class definition) AND the implementation of the function so the argument is `User &user` – Peter Jul 31 '22 at 15:27
  • Note that `#pragma once` is not standard C++ and never will be; there are build environments where it cannot be implemented correctly. Portable code uses include guards. – Pete Becker Jul 31 '22 at 21:13

1 Answers1

0

You can simply write, in the implementation:

void Teacher::teach(User &user)
{
    user.knowledge += (*this).teachSkill;
}

No need to re-declare the class there.

Furthermore, you don't need (*this), so it's simply:

void Teacher::teach(User &user)
{
    user.knowledge += teachSkill;
}
lorro
  • 10,687
  • 23
  • 36
  • You might want to address the fact that, in the header file, `Teacher::teach()` accepts its argument by value, but you are defining that same function to accept argument by reference. Otherwise your answer is incomplete (and probably misleading for a beginner, as in this case, who doesn't appear to understand the distinction between pass by value and pass by reference). – Peter Jul 31 '22 at 15:29
  • I edited the question to make the header method file use the reference. –  Jul 31 '22 at 15:32
  • @Peter OP fixed that, it was more likely a typo. – lorro Jul 31 '22 at 15:35