Unresolved external symbol C++ - c++

I ahve a problem with a code below:
ProgrammSettings.h
#pragma once
static class ProgrammSettings
{
public:
static int fd;
};
Settings.cpp
#include "ProgrammSettings.h"
static bool LoadSettings()
{
ProgrammSettings::fd = 2; // here error Unresolved symbol!!
return true;
}
What i'm doing wrong?
Thanks!

Unlike instance variables that require only a declaration, static member variabs of the class must also be defined.
Currently, your code contains only a declaration. Add a definition of your static fd variable to a cpp file to fix the error:
int ProgrammSettings::fd;

You need to add the following line to the start of your cpp file
int ProgrammSettings::fd;

Static data members declarations in the class declaration are not definition of them
You have forgot to add the definition to match your declaration of fd.You must explicitly define your class's static data members.

Related

Why the singleton initialization failed (link error) [duplicate]

Very simply put:
I have a class that consists mostly of static public members, so I can group similar functions together that still have to be called from other classes/functions.
Anyway, I have defined two static unsigned char variables in my class public scope, when I try to modify these values in the same class' constructor, I am getting an "unresolved external symbol" error at compilation.
class test
{
public:
static unsigned char X;
static unsigned char Y;
...
test();
};
test::test()
{
X = 1;
Y = 2;
}
I'm new to C++ so go easy on me. Why can't I do this?
If you are using C++ 17 you can just use the inline specifier (see https://stackoverflow.com/a/11711082/55721)
If using older versions of the C++ standard, you must add the definitions to match your declarations of X and Y
unsigned char test::X;
unsigned char test::Y;
somewhere. You might want to also initialize a static member
unsigned char test::X = 4;
and again, you do that in the definition (usually in a CXX file) not in the declaration (which is often in a .H file)
Static data members declarations in the class declaration are not definition of them.
To define them you should do this in the .CPP file to avoid duplicated symbols.
The only data you can declare and define is integral static constants.
(Values of enums can be used as constant values as well)
You might want to rewrite your code as:
class test {
public:
const static unsigned char X = 1;
const static unsigned char Y = 2;
...
test();
};
test::test() {
}
If you want to have ability to modify you static variables (in other words when it is inappropriate to declare them as const), you can separate you code between .H and .CPP in the following way:
.H :
class test {
public:
static unsigned char X;
static unsigned char Y;
...
test();
};
.CPP :
unsigned char test::X = 1;
unsigned char test::Y = 2;
test::test()
{
// constructor is empty.
// We don't initialize static data member here,
// because static data initialization will happen on every constructor call.
}
in my case, I declared one static variable in .h file, like
//myClass.h
class myClass
{
static int m_nMyVar;
static void myFunc();
}
and in myClass.cpp, I tried to use this m_nMyVar. It got LINK error like:
error LNK2001: unresolved external symbol "public: static class...
The link error related cpp file looks like:
//myClass.cpp
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}
So I add below code on the top of myClass.cpp
//myClass.cpp
int myClass::m_nMyVar; //it seems redefine m_nMyVar, but it works well
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}
then LNK2001 is gone.
Since this is the first SO thread that seemed to come up for me when searching for "unresolved externals with static const members" in general, I'll leave another hint to solve one problem with unresolved externals here:
For me, the thing that I forgot was to mark my class definition __declspec(dllexport), and when called from another class (outside that class's dll's boundaries), I of course got the my unresolved external error.
Still, easy to forget when you're changing an internal helper class to a one accessible from elsewhere, so if you're working in a dynamically linked project, you might as well check that, too.
When we declare a static variable in a class, it is shared by all the objects of that class. As static variables are initialized only once they are never initialized by a constructor. Instead, the static variable should be explicitly initialized outside the class only once using the scope resolution operator (::).
In the below example, static variable counter is a member of the class Demo. Note how it is initialized explicitly outside the class with the initial value = 0.
#include <iostream>
#include <string>
using namespace std;
class Demo{
int var;
static int counter;
public:
Demo(int var):var(var){
cout<<"Counter = "<<counter<<endl;
counter++;
}
};
int Demo::counter = 0; //static variable initialisation
int main()
{
Demo d(2), d1(10),d3(1);
}
Output:
Count = 0
Count = 1
Count = 2
In my case, I was using wrong linking.
It was managed c++ (cli) but with native exporting. I have added to linker -> input -> assembly link resource the dll of the library from which the function is exported. But native c++ linking requires .lib file to "see" implementations in cpp correctly, so for me helped to add the .lib file to linker -> input -> additional dependencies.
[Usually managed code does not use dll export and import, it uses references, but that was unique situation.]

How to access and initialize std::list from a class

My question could be silly but I am having following problem.
Following piece of code works just fine. I have list that is global or local and can instantiate and push values correctly.
class THistory
{
public:
UInt32 index;
UInt32 navToID;
};
//Works Fine
class ML{
public:
static THistory *hist2;
};
main.cpp;
ML::hist2 = new THistory[HISTORY_BUFFER_SIZE];//global
std::list<THistory> histList;//global
histList.push_back(ML::hist2[0]);//inside main()
Problem starts when I move the list inside a class.
//Problem
class ML{
public:
static THistory *hist2;
static std::list<THistory> histList; //replace global list and put it inside ML class as static
}
main.cpp;
ML::hist2 = new THistory[HISTORY_BUFFER_SIZE];//global as before
////// Where to initialize the list?
ML::histList.push_back(CoreML::hist2[0]); //inside main()
//LINK Error Undefined symbol
error LNK2001: unresolved external symbol "public: static class std::list > CoreML::histList" (?histList#CoreML##2V?$list#VTHistory##V?$allocator#VTHistory###std###std##A)
I dont know how to initialize the list. any pointers will be helpful.
In C++, if you declare a static member variable inside of a class, you need to put a definition of that variable somewhere. The linker error you're getting is because you've declared the variable, but you haven't defined it.
In one of the C++ source files in your program, add this line:
std::list<THistory> CoreML::histList; // Define the variable.
Within a class definition static data members are only declared. You have to define them outside the class definition. For example
class ML{
public:
static THistory *hist2;
static std::list<THistory> histList; //replace global list and put it inside ML class as static
};
^^^
// before the function main
std::list<THistory> ML::histList;

Singleton pattern c++ error

Hi I have implemented a singleton pattern in c++ with the VS2010 and the compiler throw me an error !!
#ifndef __EgEngine__
#define __EgEngine__ 1
#include <esUtil.h>
#include <stdlib.h>
#include <EgGpuManager.h>
class EgEngine
{
public:
EgEngine();
static EgGpuManager GetGpuManager();
~EgEngine();
void EgInit();
private:
EgEngine(const EgEngine &other){};
EgEngine* operator = (const EgEngine &other)const {};
static EgGpuManager GpuManager; // Return this !!
ESContext esContext;
};
#endif
The other class
#ifndef __EgGpuManager__
#define __EgGpuManager__ 1
#include <EgBuffer.h>
#include <EgProgram.h>
class EgGpuManager
{
public:
EgBuffer* GetBuffer();
EgProgram* GetNewProgram();
private:
EgGpuManager();
~EgGpuManager();
EgBuffer buffer;
};
#endif
And when I try to compile I have this error:
1>EgEngine.obj : error LNK2001:
unresolved external symbol "private: static class
EgGpuManager EgEngine::GpuManager" (?GpuManager#EgEngine##0VEgGpuManager##A)
Help me please and thanks.
static EgGpuManager GpuManager; // Return this !! this guy has to be instantiated somewhere in your C++ code.
static class members have to appear in the global scope, so in the C++ file add:
EgGpuManager EgEngine::GpuManager.
By the way, you have a private constructor for EgGpuManager class, which will be a problem in this case because it is created by EgEngine. You're not implementing the singleton correctly. Use a static EgGpuManager *EgGpuManager::Get() method to return an instance, and it will instantiate the class on the first call, then you can do it with a private constructor. Otherwise make them friends.
The line "static EgGpuManager GpuManager;" inside the class declaration of EgEngine is only a declaration: You're saying that this object will exist somewhere. The linker complains that it did not find the object anywhere. To solve this, place an instantiation in one of your source files (in global scope):
EgGpuManager EgEngine::GpuManager;
You must put the instantiation of the singleton object either in the global scope, as suggested by other answers, or in the implementation of GetGpuManager() like this :
EgGpuManager& EgEngine::GetGpuManager()
{
static EgGpuManager GpuManager;
return GpuManager;
}
In this case you need to remove the declaration of GpuManager from the class definition. Also note the & to return a reference, as you certainly don't want to return a copy of the object (that would defeat the purpose of making a singleton). The advantage here is that the object will not be created until GetGpuManager() is called for the first time, whereas all statics in global scope are created when the program starts.

Why won't my C++ program link when my class has static members?

I have a little class called Stuff that I want to store things in. These things are a list of type int. Throughout my code in whatever classes I use I want to be able to access these things inside the Stuff class.
Main.cpp:
#include "Stuff.h"
int main()
{
Stuff::things.push_back(123);
return 0;
}
Stuff.h:
#include <list>
class Stuff
{
public:
static list<int> things;
};
but I get some build errors with this code:
error LNK2001: unresolved external symbol "public: static class std::list<int,class std::allocator<int> > Stuff::things" (?things#Stuff##2V?$list#HV?$allocator#H#std###std##A) Main.obj CSandbox
fatal error LNK1120: 1 unresolved externals C:\Stuff\Projects\CSandbox\Debug\CSandbox.exe CSandbox
I am a C# guy, and I am trying to learn C++ for a side project. I think that I don't understand how C++ treats static members. So please explain what I have got wrong here.
Mentioning a static member in a class declaration is a declaration only. You must include one definition of the static member for the linker to hook everything up properly. Normally you would include something like the following in a Stuff.cpp file:
#include "Stuff.h"
list<int> Stuff::things;
Be sure to include Stuff.cpp in your program along with Main.cpp.
Static data members have to be defined outside class declarations, much like methods.
For example:
class X {
public:
static int i;
};
Must also have the following:
int X::i = 0; // definition outside class declaration
Stuff::things is only declared, but it is not defined.
please use:
// Stuff.cpp
#include "Stuff.h"
std::list<int> Stuff::things;
Added: it is also a good practice to protect your header files against multiple inclusion:
// Stuff.h
#ifndef STUFF_H_
#define STUFF_H_
#include <list>
class Stuff {
public:
static std::list<int> things;
};
#endif
Just For your Information, why this works is that in C++ all global variables (including static global) are created before the execution of the main function begins.
Static member have to be declared in the class but defined in the unit (cpp file) where it is really located.
The only exception is in case the class is template: in this case you have to define the member outside the class, but you have to provide it too with the class declaration, in the header file.

Unresolved external symbol on static class members

Very simply put:
I have a class that consists mostly of static public members, so I can group similar functions together that still have to be called from other classes/functions.
Anyway, I have defined two static unsigned char variables in my class public scope, when I try to modify these values in the same class' constructor, I am getting an "unresolved external symbol" error at compilation.
class test
{
public:
static unsigned char X;
static unsigned char Y;
...
test();
};
test::test()
{
X = 1;
Y = 2;
}
I'm new to C++ so go easy on me. Why can't I do this?
If you are using C++ 17 you can just use the inline specifier (see https://stackoverflow.com/a/11711082/55721)
If using older versions of the C++ standard, you must add the definitions to match your declarations of X and Y
unsigned char test::X;
unsigned char test::Y;
somewhere. You might want to also initialize a static member
unsigned char test::X = 4;
and again, you do that in the definition (usually in a CXX file) not in the declaration (which is often in a .H file)
Static data members declarations in the class declaration are not definition of them.
To define them you should do this in the .CPP file to avoid duplicated symbols.
The only data you can declare and define is integral static constants.
(Values of enums can be used as constant values as well)
You might want to rewrite your code as:
class test {
public:
const static unsigned char X = 1;
const static unsigned char Y = 2;
...
test();
};
test::test() {
}
If you want to have ability to modify you static variables (in other words when it is inappropriate to declare them as const), you can separate you code between .H and .CPP in the following way:
.H :
class test {
public:
static unsigned char X;
static unsigned char Y;
...
test();
};
.CPP :
unsigned char test::X = 1;
unsigned char test::Y = 2;
test::test()
{
// constructor is empty.
// We don't initialize static data member here,
// because static data initialization will happen on every constructor call.
}
in my case, I declared one static variable in .h file, like
//myClass.h
class myClass
{
static int m_nMyVar;
static void myFunc();
}
and in myClass.cpp, I tried to use this m_nMyVar. It got LINK error like:
error LNK2001: unresolved external symbol "public: static class...
The link error related cpp file looks like:
//myClass.cpp
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}
So I add below code on the top of myClass.cpp
//myClass.cpp
int myClass::m_nMyVar; //it seems redefine m_nMyVar, but it works well
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}
then LNK2001 is gone.
Since this is the first SO thread that seemed to come up for me when searching for "unresolved externals with static const members" in general, I'll leave another hint to solve one problem with unresolved externals here:
For me, the thing that I forgot was to mark my class definition __declspec(dllexport), and when called from another class (outside that class's dll's boundaries), I of course got the my unresolved external error.
Still, easy to forget when you're changing an internal helper class to a one accessible from elsewhere, so if you're working in a dynamically linked project, you might as well check that, too.
When we declare a static variable in a class, it is shared by all the objects of that class. As static variables are initialized only once they are never initialized by a constructor. Instead, the static variable should be explicitly initialized outside the class only once using the scope resolution operator (::).
In the below example, static variable counter is a member of the class Demo. Note how it is initialized explicitly outside the class with the initial value = 0.
#include <iostream>
#include <string>
using namespace std;
class Demo{
int var;
static int counter;
public:
Demo(int var):var(var){
cout<<"Counter = "<<counter<<endl;
counter++;
}
};
int Demo::counter = 0; //static variable initialisation
int main()
{
Demo d(2), d1(10),d3(1);
}
Output:
Count = 0
Count = 1
Count = 2
In my case, I was using wrong linking.
It was managed c++ (cli) but with native exporting. I have added to linker -> input -> assembly link resource the dll of the library from which the function is exported. But native c++ linking requires .lib file to "see" implementations in cpp correctly, so for me helped to add the .lib file to linker -> input -> additional dependencies.
[Usually managed code does not use dll export and import, it uses references, but that was unique situation.]