0

Suppose I have a class that only has static members:

OnlyMaths.h:

#include "2DData.h"

class OnlyMaths{
public:
  static double average(2DData* a); // Will call 2DData's functions
  //... more static functions
private:
  OnlyMaths() {} // Non-instantiable class
};

And that 2DData is a class that uses OnlyMaths:

2DData.h:

#include "OnlyMaths.h"

class 2DData{
public:
  2DData(double x, double y);
  double average() {
    return OnlyMaths::average(this); // Uses static function
  }
};

Both classes need to know each other (and their methods) in order to perform their functions, but, as I wrote it, there is a circular inclusion and it wont compile.

How do I make a "static" class like OnlyMaths know other classes it needs in it's functions and have it's static functions called anywhere? Surely there is a correct way of doing this.

Note: Please assume that all *.h files are define protected with #ifndef ... as usual.

EDIT:

Some circular dependencies questions, like this, are given solutions that revolve around forward declaration. In this case this is not a possibility, as not only both classes need to know each other but also they need to know each other's functions.

By the difficulty in finding a simple solution I'm starting to think that the way I'm going about the problem may not be right, so let me clarify my goal:

The goal is to have a file OnlyMaths.h contain all the functions that do mathematics operations on all data types I have in my project. This functions can be called anywhere in the project, sometimes even inside the classes OnlyMath's operates on.

mrflash818
  • 930
  • 13
  • 24
A. Vieira
  • 1,213
  • 2
  • 11
  • 27
  • 5
    I find "static class" to be an anti-pattern. You are using it to implement a namespace. Just use a namespace. – StoryTeller - Unslander Monica Dec 20 '17 at 14:28
  • I see, that seems like good advice. But won't I still have the same linking/including issue? – A. Vieira Dec 20 '17 at 14:33
  • My comment is by no means an answer to your main query. It's "on the side" advice – StoryTeller - Unslander Monica Dec 20 '17 at 14:40
  • 1
    Possible duplicate of [Resolve build errors due to circular dependency amongst classes](https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes) – SirGuy Dec 20 '17 at 14:43
  • I would recommend to use `OnlyMaths` as a `namespace` and pass only the data to the `average` function, not the pointer, for example: `OnlyMaths::average(this->x, this->y);` – KelvinS Dec 20 '17 at 14:57
  • @KelvinS I see what you mean. Indeed I'm going to turn `OnlyMaths` into a namespace only, but passing the arguments won't always be a solution in my general case. – A. Vieira Dec 20 '17 at 15:05

1 Answers1

2

One solution is to include 2DData.h in OnlyMaths.cpp:

OnlyMaths.h :

class 2DData; // Declaration only.
class OnlyMaths{
public:
  static double average(2DData* a); // Will call 2DData's functions
  //... more static functions
private:
  OnlyMaths() {} // Non-instantiable class
};

OnlyMaths.cpp :

#include <OnlyMaths.h>
#include <2DData.h>
double OnlyMaths::average(2DData* a)
{
    a->method();
}

This way, 2DData's functions are available for any OnlyMaths's functions and vice-versa, without circular dependencies.

A. Vieira
  • 1,213
  • 2
  • 11
  • 27
M.L.
  • 728
  • 4
  • 12
  • Ah. So your solution is to include 2DData in the .cpp file. I see. – A. Vieira Dec 20 '17 at 15:55
  • Don't forget the forward declaration in the header as well. This says that there is some class named '2DData' but not how it is implemented. You can then define and call functions that pass around pointers or references to this class without needing to include the full definition until you actually try to access any members/functions of the class. – Sean Burton Dec 20 '17 at 16:47
  • 1
    Might be good to point out that this relies on NOT using inline function definitions in the .h files. Functions are declared in the .h files but defined in .cpp files where all the declarations from both .h files are visible. – Zan Lynx Dec 20 '17 at 17:55