1

I am currently trying to implement a class with the Singleton Pattern in C++. But I get following linking error:

projectgen.cpp:(.bss+0x0): multiple definition of `Metadata::metadata'; C:\Users\adria\AppData\Local\Temp\ccdq4ZjN.o:main.cpp:(.bss+0x0): first defined here collect2.exe: error: ld returned 1 exit status

What's the error's cause?

Metadata.h: (Singleton class)

#pragma once
class Metadata
{
public:

    Metadata(Metadata &other) = delete;
    void operator=(const Metadata &other) = delete;

    static Metadata *getInstance()
    {
        return metadata;
    }

    static void createInstance(Ctor &params)
    {
        if (!metadata)
        {
            metadata = new Metadata(params);
        }
    }
protected:
    Metadata(Ctor &params)
    {
        m_vars = params;
    }

    static Metadata *metadata;

private:
    Ctor m_vars;
}

Metadata* Metadata::metadata = nullptr;

main.cpp:

#include "metadata.h"

int main(void)
{
    Ctor ctor;
    Metadata::createInstance(ctor);
    Metadata* data = Metadata::getInstance();
    return 0;
}

projectgen.cpp:

#include "metadata.h"

void ProjectGenerator::test()
{
    Metadata* data = Metadata::getInstance();
}
Adrian H.
  • 13
  • 3
  • `Metadata* Metadata::metadata = nullptr;` cannot be in the header file, it needs to be in a ".cpp" file – UnholySheep Jul 17 '22 at 18:35
  • You need to instantiate the static variable `metadata` somewhere in a cpp file not in an .h file. There error is surely caused because you have metadata.h included somewhere else. – ALX23z Jul 17 '22 at 18:36
  • 1
    Reopened, not a duplicate. This is simply a coding error. It has nothing to do with singletons. – Pete Becker Jul 17 '22 at 20:19

2 Answers2

1

An #include statement is logically equivalent to taking the included header file and physically inserting it into the .cpp file that's including it.

Metadata* Metadata::metadata = nullptr;

In the included header file, this defines this particular static class member. Therefore, every .cpp file that includes this header file defines this class member. You have two .cpp files that include this header file, and each one defines the same static class member.

This violates C++'s One Definition Rule. An object can be defined exactly once.

Simply move this definition to one of your .cpp files.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
0

The accepted answer is correct, I just want the option to declare the variable inline. This allows multiple definitions which are then taken as one.

inline Metadata* Metadata::metadata = nullptr;

Michael Chourdakis
  • 10,345
  • 3
  • 42
  • 78