0

I have a class ResourceManager that I try to use as a singleton here. It has a file resources.hpp and resources.cpp that I list below. The last code listing is the usage of ResourceManager::instance() and the error message below. I tried a lot of things like forward declarations etc. but could not find a way to let the compiler succeed.

resources.hpp

namespace X11 {
      class ResourceManager {
      private:
        static ResourceManager* _instance;
        ResourceManager() {
          //logic
        };
        ResourceManager (const ResourceManager&);
        ~ResourceManager() = default;
      public:
        static ResourceManager* instance();
        std::vector<sf::Font> fonts;
      };
    }

resources.cpp

 #include "resources.hpp"

    namespace X11 {
      ResourceManager* ResourceManager::_instance = 0;
      ResourceManager* ResourceManager::instance() {
        if (!ResourceManager::_instance)
          ResourceManager::_instance = new ResourceManager();
        return ResourceManager::_instance;
      }
    }

Usage (initialized.cpp)

 #include "initializer.hpp"
  // initializer.hpp includes "resources.hpp"

  void Initializer::init_right_bar(Menu& menu) {
    // logic
    text.setFont(ResourceManager::instance()->fonts[0]);
    // logic
  }

Error message

[ 30%] Building CXX object CMakeFiles/vilsoc.dir/src/initializer.cpp.o
[ 40%] Building CXX object CMakeFiles/vilsoc.dir/src/vilsoc.cpp.o
[ 50%] Linking CXX executable vilsoc
/usr/bin/ld: CMakeFiles/vilsoc.dir/src/initializer.cpp.o: in function `X11::Initializer::init_right_bar(X11::Menu&)':
initializer.cpp:(.text+0x1715): undefined reference to `X11::ResourceManager::instance()'
collect2: error: ld returned 1 exit status

SOLVED The comments led to the conclusion that I wasn't updating my makefile through CMake and therefore the linker could not find the source file.

xetra11
  • 7,671
  • 14
  • 84
  • 159
  • 1
    Did you `#include "resources.cpp"` in initialized.cpp? – Zachary Oldham Jul 17 '19 at 18:14
  • @ZacharyOldham I included "resources.Hpp" not .cpp – xetra11 Jul 17 '19 at 18:15
  • You have a linker error, not a compiler error. Your issue is not missing includes, it's not linking the file defining the missing symbol. – Jesper Juhl Jul 17 '19 at 18:17
  • Unrelated: [A much better singleton](https://stackoverflow.com/a/1008289/4581301) – user4581301 Jul 17 '19 at 18:17
  • Can you post your initializer.hpp? Are you using the right namespace? – Piccolo Jul 17 '19 at 18:18
  • Note that this attempt at singleton has undefined behaviour if `ResourceManager::instance()` is called from multiple threads. – eerorika Jul 17 '19 at 18:19
  • I think you need to `#include 'resources.hpp` in resources.cpp and `#include resources.cpp` in resources.hpp – Zachary Oldham Jul 17 '19 at 18:20
  • In `initializer.cpp` I added `#include "../src/resources.cpp" `. Can somebody explain me why it now works with linking? I thought `#include "resources.hpp` would be enough as always – xetra11 Jul 17 '19 at 18:21
  • @ZacharyOldham why is that? I don't understand the problem – xetra11 Jul 17 '19 at 18:22
  • @xetra11 resources.cpp definitely needs access to the code in resources.hpp. You actually probably don't need the other one, as long as you include both files in initialized.cpp – Zachary Oldham Jul 17 '19 at 18:24
  • This makes it sound like resources.cpp is not being compiled and linked. If it was being compiled and linked and you included it ([don't include cpp files](https://stackoverflow.com/questions/1686204/why-should-i-not-include-cpp-files-and-instead-use-a-header)) in another file, you'd get multiple definitions error. – user4581301 Jul 17 '19 at 18:39
  • @user4581301 that's why it's all so confusing for me. I don't want to include the cpp file but it seems to be the only way to get it linked – xetra11 Jul 17 '19 at 19:07
  • Did you manufacture the makefile by hand or was it generated for you by a program? If you have no idea what I just said, it's the latter. In that case, whatever tool you are using to write your code is not acknowledging that resources.cpp is part of the project and is not compiling and linking it. How to add resources.cpp to the project depends on the tool. – user4581301 Jul 17 '19 at 19:14
  • @user4581301 you sir are fully correct. I am used to CLion where Cmake is updated automatically. Having this project checkout out on Linux now using Emacs I had to run `cmake` for every new source file added. Please make this an answer so I can – xetra11 Jul 17 '19 at 19:59
  • 1
    No need. It's covered by answer three of the duplicate. The problem with that duplicate is it sometimes a bit of work to figure out which answer applies to the question. – user4581301 Jul 17 '19 at 21:22

0 Answers0