How to call static library function in a C++ class? [duplicate] - c++

This question already has answers here:
How to implement static class member functions in *.cpp file?
(7 answers)
What does "static" mean in C?
(20 answers)
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 3 years ago.
I have class whose header file is defined as:
namespace mip {
class CustomStatic {
public:
static const char* GetVersion();
};
}
And class file is defined as:
#include "CustomStatic.h"
namespace mip {
static const char* GetVersion() {
return "hello";
}
}
I am accessing this static function from my main class
#include "CustomStatic.h"
#include <iostream>
using std::cout;
using mip::CustomStatic;
int main() {
const char *msg = mip::CustomStatic::GetVersion();
cout << "Version " << msg << "\n";
}
When I try to compile it using-
g++ -std=c++11 -I CustomStatic.h MainApp.cpp CustomStatic.cpp
I am getting error as:
Undefined symbols for architecture x86_64:
"mip::CustomStatic::GetVersion()", referenced from:
_main in MainApp-feb286.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code
1 (use -v to see invocation)

your static function is not properly implemented in the cpp file...
you need to do something like
//.h
namespace mip
{
class CustomStatic
{
public:
static const char* GetVersion();
};
}
//.cpp -> note that no static keyword is required...
namespace mip
{
const char* CustomStatic::GetVersion()
{
return "hello";
}
}
//use
int main(int argc, char *argv[])
{
const char* msg{mip::CustomStatic::GetVersion()};
cout << "Version " << msg << "\n";
}

Related

error using static variable unresolved external symbol / undefined reference [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 3 years ago.
I am using static variable. After referring to Unresolved external symbol on static class members, I modified the program with Abc::ct
#include <iostream>
class Abc
{
private:
static unsigned int ct;
public:
void f1()
{
for (int i = 0; i < 5; ++i)
f2();
}
void f2() {
Abc::ct = 0;
if (Abc::ct == 0)
std::cout << "Zero iteration\n";
std::cout << Abc::ct << "\t";
++Abc::ct;
}
};
int main()
{
Abc obj;
obj.f1();
}
but getting error as error LNK2001: unresolved external symbol "private: static unsigned int Abc::ct" in MSVC or undefined reference to Abc::ct in g++. How can I define static variable in class Abc?
You declared your static variable, but you did not define and initialize it. Above main(), but outside of your class, add the following line:
unsigned int Abc::ct = 0;
or, if you are using C++17, you can change your:
static unsigned int ct;
to:
static inline unsigned int ct = 0;
You have to define it:
unsigned int Abc::ct = 0;
Demo

C++ Linker Error: symbol(s) not found when using function templates [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 6 years ago.
I have three c++ files, sort.cpp defines a bubble sort function that takes an array, the length of the array and a function that is used to do the comparison. sort.h contains the function prototype inside a namespace. main.cpp is used to test the implementation.
sort.h:
#ifndef SORT_H
#define SORT_H
namespace sort {
template <typename T>
void bubble(T*, int, bool (*)(T, T));
}
#endif
sort.cpp:
#include "sort.h"
template <typename T>
void sort::bubble(T *array, int length, bool (*compare)(T, T)) {
while (length != 0) {
int newLength {0};
for (int i {0}; i < length - 1; ++i) {
if (compare(array[i], array[i+1])) {
T temp {array[i]};
array[i] = array[i+1];
array[i+1] = temp;
newLength = i + 1;
}
}
length = newLength;
}
}
main.cpp:
#include <iostream>
#include "sort.h"
bool larger(int x, int y) {
return x > y;
}
int main() {
int arr[] {3, 5, 1, 3, 7, 2};
sort::bubble(arr, 6, larger);
for(const auto e: arr)
std::cout << e << ' ';
std::cout << '\n';
return 0;
}
When I compile with g++ main.cpp sort.cpp -std=c++11 I get the error
Undefined symbols for architecture x86_64:
"void sort::bubble<int>(int*, int, bool (*)(int, int))", referenced from:
_main in main-767bbd.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Do I get the error because the compiler doesn't know which types I'm going to use when compiling sort.cpp? So the compiler doesn't generate any function off of the template and then the linker can't find it when I use it in main.cpp?
How can I solve this issue?
Don't use two files for templates, just only one: sort.hpp
There is a workaround but is not recommended.

initialize map with static member variable

I do not understand why I cannot use a public const static member of a class in the initializer list of a map (probably any container). As I understand it "MyClass::A" is an rvalue, it seems like it should be the exact same as the case where I am using "THING" which is also a static const just outside of a class.
Here is the error:
Undefined symbols for architecture x86_64:
"MyClass::A", referenced from:
_main in map-380caf.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
And here is the code:
#include <iostream>
#include <map>
#include <string>
static const int THING = 1;
class MyClass {
public:
static const int A = 1;
};
int
main()
{
int a;
typedef std::map<int, std::string> MyMap;
// compiles and works fine
a = MyClass::A;
std::cout << a << std::endl;
// compiles and works fine
MyMap other_map = { {THING, "foo"} };
std::cout << other_map.size() << std::endl;
// Does not compile
MyMap my_map = { {MyClass::A, "foo"} };
std::cout << my_map.size() << std::endl;
return 0;
}
UPDATE 1:
Using clang on OS X:
Apple LLVM version 7.0.0 (clang-700.0.72)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
compiler flags:
clang++ map.cc -std=c++1y
Something in the map code probably tried to take the address of a reference to your int.
The class definition here:
class MyClass {
public:
static const int A = 1;
};
does not actually create any memory for A. In order to do that you have to do in the header file:
class MyClass {
public:
static const int A;
};
and in a CPP file:
const int MyClass::A = 1;
Or I guess with the newest C++ versions you can leave the = 1 in the header and just declare the storage in the CPP file with:
const int MyClass::A;

linker error with classes in c++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is an undefined reference/unresolved external symbol error and how do I fix it?
I have created this code
class Game{
static SDL_Surface* screen;
public:
//Initiate Game(SDL_Graphics, folder for output.....)
static void initialize();
static void initializeScreen();
};
void Game::initializeScreen()
{
Game::screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_DOUBLEBUF |SDL_HWSURFACE |SDL_SWSURFACE);
SDL_Init(SDL_INIT_VIDEO);
Game::screen == NULL ? printf("SDL_Init failed: %s\n", SDL_GetError()):printf("SDL_Init initialized\n");
SDL_WM_SetCaption("SDL Animation", "SDL Animation");
}
It compiles but I get e linker error, how can I fix this?
1>game.obj : error LNK2001: unresolved external symbol "private: static struct SDL_Surface * Game::screen" (?screen#Game##0PAUSDL_Surface##A)
Edit: This is how I fixed it, in game.cpp
added this
SDL_Surface* Game::screen;
outside of any function*
You have to define static (variable) members (not functions) in seperate source files(*.cpp) and link against them.
for example:
//MyClass.h
class MyClass {
static int x;
};
//MyClass.cpp
#include "MyClass.h"
int MyClass::x;
You need to add the following definition in your cpp file SDL_Surface* Game::screen = NULL.
Here is an example code where you can have a static variable without defining it in the cpp file using a function.
#include <iostream>
struct Lazy {
static int& GetValue() {
static int a = 0;
return a;
}
};
int main() {
std::cout << Lazy::GetValue() << std::endl;
int& a = Lazy::GetValue();
a = 1;
std::cout << Lazy::GetValue() << std::endl;
}

Linking error for a naive singleton class in C++

My code is:
class cMySingleton{
private:
static bool bInstantiated;
int mInt;
cMySingleton(){
mInt=0;
}
public:
cMySingleton(int c){
if (bInstantiated){
cout << "you can only instantiated once";
}
else {
cMySingleton();
mInt=c;
}
}
};
int main () {
cMySingleton s(5);
cMySingleton t(6);
}
The linker keeps complaining:
Undefined symbols for architecture x86_64:
"cMySingleton::bInstantiated", referenced from:
cMySingleton::cMySingleton(int) 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)
What is going on? C++ novice here~~
you should initialize static field.
http://ideone.com/Y1huV
#include <iostream>
class cMySingleton{
private:
static bool bInstantiated;
int mInt;
cMySingleton(){
mInt=0;
}
public:
cMySingleton(int c){
if (bInstantiated){
std::cout << "you can only instantiated once";
}
else {
cMySingleton();
mInt=c;
}
}
};
bool cMySingleton::bInstantiated = true;
int main () {
cMySingleton s(5);
cMySingleton t(6);
}
More information you can be find here:
Static Data Member Initialization
there was also missing include and std:: around cout.
Initialize
static bool bInstantiated;
outside of cMySingleton
bool CMySingleton::bInstantiated;
Dont forget to initialize your static member outside of your class declaration in .cpp file:
bool cMySingleton::bInstantiated = false;