1

I encountered a this kind of problem while writing my code how do I work around this?

second.h is :

#pragma once
#include "first.h"

class second : public first
{
private:
    int step;
public:
    second(int value, int s) :first(value), step(s) {}

    void increase() {
        counter += step;
    }

};

and first.h is :

#pragma once
class first 
{
protected:
    int counter;
public:
    first():counter(0){}

    first(int a) :counter(a) {}

    virtual void increase() {
        counter++;
    }

    second getequivalent(int step) {
        return second(counter, step);
    }
};

My question is, how do i get method

second getequivalent(int step) {
        return second(counter, step);
}

working in class "first"?

ankit
  • 171
  • 1
  • 1
  • 11
  • 1
    May be OT but you might want to rethink your design. If you change the direction of inheritance you would not need to override functions. You may not need two classes at all. – Simon Kraemer May 13 '20 at 09:28

1 Answers1

1

You have to implement the method after full definition of second is available.

As you're writing non-template classes, I'd suggest moving all implementations to separate first.cpp/second.cpp files and linking them together.

So your first.h would look like

#pragma once
class second;  // Forward declaration to make compiler know that `second` is a class.
               // Better option would be to #include "second.h", but you cannot
               // do that because `class second` needs _full_ definition of `class first`
               // because of inheritance, hence it _has_ to #include "first.h"
               // without any troubles.
class first 
{
protected:
    int counter;
public:
    first();
    first(int a);
    virtual void increase();
    second getequivalent(int step);  // Compiler don't need to know anything
                                     // about second at this point.
};

and first.cpp would look like

#include "first.h"  // Make full definition of class first available.
#include "second.h"  // Make full definition of class second available.

first::first():counter(0){}

first::first(int a) :counter(a) {}

/*virtual */ void first::increase() {  // Should not specify 'virtual' in definition outside the class.
    counter++;
}

second first::getequivalent(int step) {
    return second(counter, step);
}
yeputons
  • 8,478
  • 34
  • 67
  • 1
    Are you sure that 'Compiler don't need to know anything about second at this point ?'. As far as i know it is valid for returning `second*`, not `second` with forward declaration. – calynr May 13 '20 at 09:25
  • 1
    You cannot define a `second` field, but you can declare a function returning or accepting `second` by-value, see [here](https://stackoverflow.com/a/553869/767632). – yeputons May 13 '20 at 09:31
  • However, if you try to call `first::getequivalent` without including `second.h`, now that would be an error, IIRC. – yeputons May 13 '20 at 09:32
  • *"Better option would be to #include "second.h""*. Whereas some prefer `#include` over forward definitions, some prefers the reverse (faster compilation). Both have their pro/cons. So "better" is opinion based or "style". – Jarod42 May 13 '20 at 09:32
  • my class was very small so I thought I could getaway by defining everything in a single .h file. I guess cant do that now. Or is there any other option? – ankit May 13 '20 at 09:35
  • 1
    @ankit: Alternative to cpp would be to put `first::getequivalent` in `second.h` after `second` definition... Which seems not a logical place. Another option would be to merge `first.h` and `second.h` into a single header. – Jarod42 May 13 '20 at 10:15
  • This works but `second` should be forward declared in `first.h`. – ankit May 13 '20 at 10:28