Static Collection of Instances C++? [duplicate] - c++

This question already has answers here:
Static constructor in c++ and fatal error LNK1120: 1 unresolved externals
(4 answers)
Closed 8 years ago.
I have a class Phone, I want it, when created to add itself to a static collection of phones. So I have the collection:
static vector < class Phone* > instances;
And in the constructor I do this:
Phone::instances.push_back(this);
But the linker throws an unresolved external symbol, why is that? What am I doing wrong? I didn't find a similar question. Is it necessary to add the instance outside the constructor? Or do I have to have the collection on another class? Thank you very much.

You must declare static member outside your class.
In your header:
class Phone{
...
static vector < class Phone* > instances;
...
};
In your cpp you need to create the instance of it:
//on global or namespace scope
vector <Phone*> Phone::instances;

Also, just a side note, not a direct answer to your question, it would be better to have a vector of "std::shared_ptr"s, rather than raw pointers. But if you a vector of std::shared_ptr, you will not be able to add "this" into that vector, so you would have to add one more thing to your class which will be able to access "this" in your class wrapped in std::shared_ptr. Here is what you can do:
class Phone : public std::enable_shared_from_this<Phone>
{
static vector<std::shared_ptr<Phone>> instances;
}
//then somewhere in your code:
Phone::instances.push_back(shared_from_this());
And in your .cpp file:
vector<std::shared_ptr<Phone>> Phone::instances;

Related

Pointer to a logger class provide for all other classes? [duplicate]

This question already has answers here:
Error logging in c++
(3 answers)
Closed 7 years ago.
I have a Logger class in my C++ application. This class has public methods like writeDebug(std::string & str) , can write to a debug output file and it works for me very good. The object is being created on application start by the first main class and there it is stored as a Logger * myLogger; object.
Since I have other classes as well, I would like to provide this logging functionality to those classes as well.
Currently I oberhead the myLogger pointer to toher classes in their contructor, and all the other classes store this very same Logger pointer when being created --> all other classes has this Logger * myLogger pointer stored:
Other_XY_Class::Other_XY_Class(Logger * logger, ...)
: localLoggerPtr{logger} { //.. }
==> localLoggerPtr (in class Other_XY_Class) == myLogger (in main application class)
I can imagine that there is a more convenient / elegant way to handle that ?
Since you only have one instance, why not use a Singleton for that?
Something along this lines:
class foo {
private:
void bar();
static foo Instance;
public:
static void Bar() { Instance.bar(); }
}

How to use an array within a class? [duplicate]

This question already has answers here:
Unresolved external symbol on static class members
(6 answers)
Closed 7 years ago.
I'm currently designing some code on QT that is built across multiple source. I want to create an array in one source and be able to access it in another source.
Currently in my Header I have class
Array_Class : public QString
{
public:
static QString Data_Array [2];
};
I don't think I need a constructor as I'm going to "populate" the array before I read it.
currently in my source.cpp I have
Array_Class::Data_Array[0]= "foo";
Array_Class::Data_Array[1]= "bar";
however this gives me the error message undefined reference to "Array_Class::Data_Array". What am I missing? thanks
So far, you have only declared your array:
Array_Class : public QString
{
public:
static QString Data_Array [2]; // -> only a declaration!
};
In order to use it, you must now define it. To do this, you need to place somewhere in your .cpp:
QString Array_Class::Data_Array [2];

How to initialize static fields in C++? [duplicate]

This question already has answers here:
Defining static members in C++
(6 answers)
Closed 7 years ago.
I need a class with static std::vector<int> simples (first N simple numbers). I created it in static method __init__, which is called before any instance of MyClass is created:
class MyClass
{
public:
MyClass()
{
/* I need to use MyClass::simples here */
printf("%d\n", (int)MyClass::simples.size());
/* But I get the error here :( */
}
static void __init__(int N)
{
simples.push_back(2);
/* ...
here I compute first N simple numbers and fill
MyClass::simples with them
*/
}
private:
static std::vector<int> simples;
};
int main()
{
MyClass::__init__(1000);
MyClass var;
return 0;
}
But when I tried to use this vector in construction, I get undefined reference to 'MyClass::simples' error. How to solve my problem?
When defining a static member in C++, you need to write it two times: first in class definition as you did:
static std::vector<int> simples;
And then outside (preferably in an external .cpp file):
std::vector<int> MyClass::simples;
If you know about C language, this can help you: static members in C++ are comparable from global variables in C: defined as a prototype in .h file included whenever you need it, and value initialized in one .c/.cpp file.
You have to define the static data member outside the class
std::vector<int> MyClass::simples;
Within the class definition it is only declared.

How do I set static variables in C++ classes? [duplicate]

This question already has answers here:
How to initialize private static members in C++?
(18 answers)
Closed 8 years ago.
I have a class like this:
class example {
public:
static void setStaticVar() { example::var = 1; };
private:
static int var;
};
But it gives me linker errors and I have no idea why.
I want to store some data in the variable that is the same for every instance. That's why I want to use a static variable instead of an instance variable (with an instance variable I would store the same data in every single instance of the class which is a waste of memory).
How do I do this?
In the source file
int example::var = 0;
You need to initialize the variable once. In one .cpp, outside of any functions, you have to initialize the variable:
int example::var = 0;
You must initialize it out of the class definition.
Try this.
class example { ... };
// initialize it to avoid linker errors
int example::var = 1;

unresolved externals c++, default constructor

I am working on a VS2010C++ console application, and have created a Manager class that holds static, and dynamic objects of the same type (Thing) one of which being a vector.
I originally got an error on the constructor of the manager class stating that the class it was composed of had no default constructor (but it shouldn't have a default constructor because the objects need to be instantiated at run time, and with run time entered information) I ended up creating a default constructor for the held class (that does nothing), and then I was able to continue after that.
then I got done with all the functionality I need for the program, and I get a whole bunch of LNK2019 "something about unresolved external symbol MethodA referenced in functionB.
first why do I need a default constructor for the managed class if I need it to be done at run-time?
second how do I get rid of these LNK2019? (all of these methods are marked inline in the headers, and its only references to, or from the manager class, and there are no naming conflicts.) as a small note could it have something to do with having to mix access modifiers of . (for the static members), and -> (for the dynamic members)?
Edit:
was able to get rid of the default constructor by limiting its need to a single method, and modifying the other statics to dynamic
for the linker error: in Thing.h
class Thing{
public : int ** Array;
public : int size;
public : Point pi;
public : SinglyLinkedList * moves;
...
public :inline bool operator==(const Thing * _thing);
...
};
Thing.cpp
bool Thing::operator==(const Thing * _Thing){
for(int ii = 0; ii < m; ii++){
for(int jj = 0; jj < m; jj++){
if(Array[ii][jj] != _Thing->Array[ii][jj]){
return false;
}
}
}
return true;
}
ThingMgr.h
class ThingMgr {
public : Thing * control;
public : Thing * Current;
public : Thing * previous;
public : int size;
main.cpp
int _tmain{
...
ThingMgr * TestTings= new ThingMgr(num);
...
if(testThings->control->operator==(testThings->Current)){ // pretty sure its here as it is not called anywhere else in the function.
...
}
error
1>Project_1.obj : error LNK2019: unresolved external symbol "public: bool __thiscall Thing::operator==(class Thing const *)" (??8Board##QAE_NPBV0##Z) referenced in function _wmain
I thought it might have been needing to put parentheses in, but then VS yelled about expecting a member. there are other functions, but maybe if I can figure out what is going on here then those should be fixable.
It would help to see the code. From the sounds of it, you create a std::vector<T> with you type which is given some non-zero size: the std::vector<T> needs to initialize the objects and you apparently didn't give it an object it could copy. You might want to create an empty std::vector<T> and use push_back() your readily constructed objects (or emplace() them if you have a C++2011 system)
With respect to link errors: you apparently didn't define some of the functions you are using. What these are exactly is impossible to tell with the vague description you have given. You'd need to provide more details e.g. the exact link error together with the assumed implementation.