2

I am implementing a static library in C++. The problem I have is that in the header file that goes with the library other header files are included. How do I wrap the library so that these files are not visible? For example, say I have this code:

//MyLib.h
#ifndef MyLib_h
#define MyLib_h    
class Math
{
public:
  // this method returns the mass of the Universe
  static double CalcMassOfTheUniverse();
}
#endif

//MyLib.cpp
#include MyLyb.h
double Math::CalcMassofTheUniverse()
{
  // do some complicated calculations here
  return result;
}

Then I find that in order to calculate the mass of the Universe easier I have to have a variable of type UniverseObject:

//MyLib.h
#ifndef MyLib_h
#define MyLib_h
#include "UniverseObject.h"
class Math
{
  public:
    double string CalcMassOfTheUniverse();
  private:
    UniverseObject m_Universe; // used to calculate the mass
}
#endif

//MyLib.cpp
#include MyLib.h
double Math::CalcMassofTheUniverse()
{       
  // Use m_Universe to calculate mass of the Universe 
  return massOfTheUniverse;
}

The problem is that now in the header file I include "UniverseObject.h". I understand that this is necessary since the Math class uses it but is there a way to wrap the class in such a way that users do not know what headers I use and so on? I am asking this since it would be easier to give people only one header and the library instead of a bunch of headers.

Josiah
  • 4,663
  • 2
  • 31
  • 49
user1523271
  • 1,005
  • 2
  • 13
  • 27
  • "The problem I have is that in the header file that goes with the library other header files are included" And why is that a problem for you? You (and the STL, and every library I know) use include guards, thus redundant declarations are skipped anyway. – decltype_auto Nov 24 '15 at 15:36
  • 6
    You could use forward declarations and the [pimpl idiom](https://en.wikibooks.org/wiki/C%2B%2B_Programming/Idioms) – πάντα ῥεῖ Nov 24 '15 at 15:36
  • pimpl idiom, interface may help. – Jarod42 Nov 24 '15 at 15:36
  • 2
    Don't forget to terminate your class declarations with `;`. C++ is not Java. As for your requirement, just learn to live with it. – Bathsheba Nov 24 '15 at 15:43

1 Answers1

1

easier [...] to have a variable of type UniverseObject

A "Universe" is a eo ipso a candidate for a Singleton

universe.h:

#ifndef UNIVERSE_H
#define UNIVERSE_H 1

// Singleton pattern
class Universe {
public:    
    static Universe& instance() noexcept {
        static Universe universe; // there shall be light
        return universe;          // now there is light; that's good
    }

    double guess_total_energy() const noexcept;

private:
    Universe() noexcept;
    ~Universe() noexcept;

    Universe(const Universe&) = delete;
    Universe(Universe&&) = delete;
    Universe& operator=(const Universe&) = delete;
    Universe& operator=(Universe&&) = delete;
};
#endif // ifndef UNIVERSE_H

universe.c++:

#include <iostream>
#include "universe.h"

Universe::Universe() noexcept {
    std::cout << "BANG! (Universe constructor called)" 
              << std::endl; 
}

Universe::~Universe() noexcept {
    std::clog << "Universe destructor called." 
              << std::endl; 
}

double 
Universe::guess_total_energy() const noexcept {
    return 0.;
}

main.c++:

#include <iostream>
#include "universe.h"

int main() {
    std::cout << "In the beginning..." << std::endl;

    // or whereever you need that instance
    Universe& universe = Universe::instance(); 

    std::cout << std::scientific 
              << universe.guess_total_energy() << "J guessed"
              << std::endl;

    return 0; // EXIT_SUCCESS;
}

compilation:

g++-4.9 -std=c++11 -Wall -pedantic  main.c++ universe.c++
./a.out

output:

    In the beginning...
    BANG! (Universe constructor called)
    0.000000e+00J guessed
    Universe destructor called.

As you may take it from the output, the "Universe" object is created on first demand, and also cleaned up on program termination.

decltype_auto
  • 1,706
  • 10
  • 19