Accesing staic variable from static function C++ - c++

class A {
public:
static int i;
static int inc();
};
int A::inc() {
i++;
return i;
}
int main() {
A::inc();
}
As we know that we can access static member variables from static method.
But this code is giving me a error
"A::i", referenced from:
A::inc() in ccn8PKhC.o
ld: symbol(s) not found for architecture x86_64
Can some one please tell me what am i missing

This is a linker error. You've declared the variable, but you haven't defined it, so the linker can't find it.
Add this:
int A::i = 0;
somewhere globally in a .cpp file (outside your class and any function) to define it. If you have multiple .cpp files in your project, the definition needs to be in only one of them.

Related

C++ can't define virtual function OUTSIDE classes and header file

As function name had been already declared in header file: function.h and header file were preloaded in OJ, I need to define myAdd in main.cpp, aka OUTSIDE classes. However, most tutorial I can find online about virtual function just define what the function should do INSIDE the class.This is header file:
#ifndef _FUNCTION_H_
#define _FUNCTION_H_
class abstractAdd
{
public:
abstractAdd(){};
~abstractAdd(){};
virtual int myAdd(int a, int b) = 0;
};
class Implement : public abstractAdd
{
private:
public:
Implement();
~Implement();
int myAdd(int a,int b);
};
;
#endif
I have tried this in main.cpp
//include every libraries needed
#include "function.h"
int Implement::myAdd(int a,int b)
{
int c=a+b;
return c;
}
int main(){
abstractAdd& ra = *new Implement();
string input;
while(getline(std::cin, input)){
istringstream testcase(input);
int a,b;
testcase >> a;
testcase >> b;
cout << ra.myAdd(a,b) << endl;
}
return 0;
}
But compiler said:
Undefined symbols for architecture x86_64:
"Implement::Implement()", referenced from:
_main in cc3KANpW.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
How can I implement the function OUTSIDE classes and header files?
new Implement() will create an object. That entails calling the constructor. You declared a constructor Implement();, but didn't define it anywhere.
So the linker is complaining because it can't find the constructor definition.
If you simply wish to use the default constructor as a compiler would define it, you can declare it as follows:
Implement() = default;
It will be defaulted, and defined inline.
Same goes for Implement's destructor as well.
As an aside, while your program is small and probably hosted, it still contains a leak. You allocate with new but don't delete the created object. In real production code, that will be unacceptable. You can simplify your code and rid you self of this concern by using a smart pointer:
std::unique_ptr<abstractAdd> ra = std::make_unique<Implement>();
Now that the object is disposed of correctly when the time comes, you should also make the destructor of abstractAdd virtual as well. Because now you are destroying an object polymorphically.

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.]

Cannot access public static variable member [duplicate]

This question already has an answer here:
linker cannot find a C++ static member [duplicate]
(1 answer)
Closed 6 years ago.
I've declared a public static member to keep the total count of the instances of my class. The code is as follows:
class Hello {
public:
static int myCount;
void test(){
//do nothing
};
Hello(){
Hello::myCount += 1;
};
~Hello() {
Hello::myCount -= 1;
}
};
int main(int argc, const char * argv[]) {
// insert code here...
Hello *p1 = new Hello();p1->test();
Hello *p2 = new Hello();p2->test();
cout << Hello::myCount;
return 0;
}
However, I when compile, it says:
Undefined symbols for architecture x86_64:
"Hello::myCount", referenced from:
_main in main.o
Hello::Hello() in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I don't know where I'm wrong. It's been years from the last time I worked with c++, so could you please suggest a solution?
Thank you.
Static members have to be defined outside of the class, e.g.:
class Hello {
public:
static int myCount;
void test(){
//do nothing
};
Hello(){
Hello::myCount += 1;
};
~Hello() {
Hello::myCount -= 1;
}
};
int Hello::myCount = 0; // definition outside of the class
(...)
Here is an example to show, that it helps to solve your problem: http://ideone.com/LVXVCc
It's all because a rule called One Definition Rule.
You can read more about this one in a context of static class members here.
In short: static int myCount declaration is not a definition of a member. Classes are usually placed in their .h/.hpp header files and are included to many other files. If those'd contain static member and lines like the one above would be a definition, it will lead to the multiple-definitions error.
To prevent that, this declaration is not treated as a definition and you must define it yourself later.

C++ Singleton fail to link on Mac OS

I am trying to create a very classic singleton on C++, Mac OS using Xcode
I create the Class MySingleton as follow:
class MySingleton{
private:
int val;
static MySingleton *instance;
MySingleton(){
val = 0;
}
public:
int getVal(){
return val;
}
void setVal(int iVal){
val = iVal;
}
static MySingleton* getInstance(){
if(instance == NULL)
instance = new MySingleton();
return instance;
}
};
Linker is complaining about static MySingleton* getInstance()
Follow the Linker message:
Undefined symbols for architecture x86_64: "MySingleton::instance",
referenced from:
MySingleton::getInstance() in main.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code
1 (use -v to see invocation)
Could somebody help on this? Perhaps I need to set something on Xcode, which by the way is version 4.2.1, and I am not able in doing this.
Thanks.
You need to define static variable in your cpp file, like this:
MySingleton *MySingleton::instance = 0;
The static member MySingleton needs to be defined in the cpp file. In the header you have have only declared it. See this for more information: Why do static variables need to be declared twice in C++
As far as I can see, you've declared static MySingleton *instance but haven't defined it anywhere.

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.]