c++ static member, how do I test it - c++

I have a class in foo.h containing a static member
class foo {
public:
static vector<int> a;
static void Init() { // Init a }
}
Everything works fine until I have a testing file
foo_test.cpp which is testing class foo. But in the
testing file, the static member a is not visible because
static member is only visible... How do I solve this?
Thanks

You will need to define a, in your cpp file add a line like:
vector<int> foo::a;
Edit: changed the data type to reflect the edit in the question

If you call foo::Init() outside the scope, you will get function re-declaration error. If you put it inside the scope, you will getting unresolved external symbol. You can only init it as int foo::a = 0;

Related

Where do I define an inner struct static object? It seems I can't

I know I have to define a static class member outside of the class in the global scope/namespace, otherwise the compiler will complain about missing symbols. So in the following I can't manage to define the inner struct:
struct MyStruct
{
struct MyInnerStruct
{
int notimportant1, notimportant2;
};
static MyInnerStruct object1;
};
int main(void)
{
MyStruct foo;
foo.object1.notimportant1 = 5; // Unresolved external symbol, I expected this to happen
return 0;
}
MyInnerStruct MyStruct::object1; // Typical definition of a static member
// MyInnerStruct is underlined, saying it's undefined
I also tried a forward declaration above it, but it said something about redefinition. Actually I was wondering also, this having to redefine every
It's because there no such symbol MyInnerStruct in the global namespace, it's inside MyStruct. I.e. you need to do
MyStruct::MyInnerStruct MyStruct::object1;
This works much the same way you define member functions outside the class.

what's the proper way to declare static mutable values

I've got a mutable static value in my program.
static int foo = 0;
regardless of private or public accessibility I don't want nasty name collisions.
I don't like things just sitting in the scope of my namespace.
So I tried the following
class aClass{
static int foo = 0;
}
Apperantly this is impossible, unless I don't assign a variable to foo.
Which is impossible for foo in my program.
What is the standard on declaring mutable statics with a default value?
I read something about people using const <T>* but that doesn't sound sane to me, and seems prone to error.
how about header:
class aClass {
static int foo;
}
cpp file
int aClass::foo;
you can then add an initialisation if you want to there.

Initialization of a static member inside a global function

My code looks like this:
class myClass{
public:
static int a;
};
void myFunc()
{
int myClass::a = 1;
}
I see the following compilation error
error C2655: 'myClass::a' : definition or redeclaration illegal in current scope
I make the following change and everything goes fine. Any idea?
class myClass{
public:
static int a;
};
int myClass::a = 1;
void myFunc()
{
}
Logically think like this:
If you never call myFunc(), myClass::a is not defined. So it must be in global scope.
In your first code snippet, potentially you may use myClass::a even without defining it, so it not allowed and former syntax is not valid C++.
Static variable must be initialized before program start, so if you initialized it in a function, there is chance that it will not be initialized at all. So the compiler should pose this as an error. Static variable is allocated at compile time (before program run). Hope this help.
If you define the static member data in a function, it's linkage is internal to the function. The linkage required for them is global.

Static function and non-static variable

In following code:
class A
{
public:
static void StaticFunction(int variable){ }
void NonStaticFunction() { }
private:
int nonStaticVariable;
};
I need to get a 'variable' and use it in 'NonStaticFunction'
I have tried making 'nonStaticVariable' static and assign its value to 'variable', but then I still would have to use static variable in 'NonStaticFunction', which throws linker error.
Error 2 error LNK2001: unresolved external symbol "public: static unsigned int A::staticVariable" (?staticVariable#A##2IA)
Are there any ways of solving it?
You need to add a definition for your static data member at namespace scope:
int A::nowStaticVariable; // Put an initializer if 0 is not OK for you
However, if your static function needs access to a non-static data member, and you're forced to make that data member static in order to make the whole thing work, that smells like bad design. Consider re-thinking it.
If you make nonStaticVariable static; i.e.
static int nonStaticVariable;
in your class then you need to provide storage for it (or the linker will complain). This is called the definition. Do this in a source file by writing
int A::nonStaticVariable;
Interestingly this is initialised to zero (unlike non-statics in C and C++ which are not initialised).
Conceptually, you need to do this because no object of class A instantiates the static variable since it's not an instance-level data member.
You don't have to use the parameter in your static function
class A
{
public:
static void StaticFunction(int // you don't need it ){ }
void NonStaticFunction() { }
private:// it can't be static and private ????
static int nonStaticVariable;
};
int A:: nonStaticVariable = 0 ;
void A::StaticFunction(/*int v */){
you can use directly your static variable and if you declared parameter in your function
v= nonStaticVariable;
}

Initialize static variables in C++ class?

I have noticed that some of my functions in a class are actually not accessing the object, so I made them static. Then the compiler told me that all variables they access must also be static – well, quite understandable so far. I have a bunch of string variables such as
string RE_ANY = "([^\\n]*)";
string RE_ANY_RELUCTANT = "([^\\n]*?)";
and so on in the class. I have then made them all static const because they never change. However, my program only compiles if I move them out of the class: Otherwise, MSVC++2010 complains "Only static constant integral variables may be initialized within a class".
Well that's unfortunate. Is there a workaround? I would like to leave them inside the class they belong to.
They can't be initialised inside the class, but they can be initialised outside the class, in a source file:
// inside the class
class Thing {
static string RE_ANY;
static string RE_ANY_RELUCTANT;
};
// in the source file
string Thing::RE_ANY = "([^\\n]*)";
string Thing::RE_ANY_RELUCTANT = "([^\\n]*?)";
Update
I've just noticed the first line of your question - you don't want to make those functions static, you want to make them const. Making them static means that they are no longer associated with an object (so they can't access any non-static members), and making the data static means it will be shared with all objects of this type. This may well not be what you want. Making them const simply means that they can't modify any members, but can still access them.
Mike Seymour has given you the right answer, but to add...
C++ lets you declare and define in your class body only static const integral types, as the compiler tells. So you can actually do:
class Foo
{
static const int someInt = 1;
static const short someShort = 2;
// etc.
};
And you can't do that with any other type, in that cases you should define them in your .cpp file.
Some answers including even the accepted answer seem to be a little misleading.
You don't have to
Always assign a value to static objects when initializing because that's optional.
Create another .cpp file for initializing since it can be done in the same header file.
You can even initialize a static object in the same class scope just like a normal variable using the inline keyword.
Initialize with no values in the same file
#include <string>
class A
{
static std::string str;
static int x;
};
std::string A::str;
int A::x;
Initialize with values in the same file
#include <string>
class A
{
static std::string str;
static int x;
};
std::string A::str = "SO!";
int A::x = 900;
Initialize in the same class scope using the inline keyword
#include <string>
class A
{
static inline std::string str = "SO!";
static inline int x = 900;
};
Since C++11 it can be done inside a class with constexpr.
class stat {
public:
// init inside class
static constexpr double inlineStaticVar = 22;
};
The variable can now be accessed with:
stat::inlineStaticVar
Static member variables must be declared in the class and then defined outside of it!
There's no workaround, just put their actual definition in a source file.
From your description it smells like you're not using static variables the right way. If they never change you should use constant variable instead, but your description is too generic to say something more.
Static member variables always hold the same value for any instance of your class: if you change a static variable of one object, it will change also for all the other objects (and in fact you can also access them without an instance of the class - ie: an object).
I feel it is worth adding that a static variable is not the same as a constant variable.
using a constant variable in a class
struct Foo{
const int a;
Foo(int b) : a(b){}
}
and we would declare it like like so
fooA = new Foo(5);
fooB = new Foo(10);
// fooA.a = 5;
// fooB.a = 10;
For a static variable
struct Bar{
static int a;
Foo(int b){
a = b;
}
}
Bar::a = 0; // set value for a
which is used like so
barA = new Bar(5);
barB = new Bar(10);
// barA.a = 10;
// barB.a = 10;
// Bar::a = 10;
You see what happens here. The constant variable, which is instanced along with each instance of Foo, as Foo is instanced has a separate value for each instance of Foo, and it can't be changed by Foo at all.
Where as with Bar, their is only one value for Bar::a no matter how many instances of Bar are made. They all share this value, you can also access it with their being any instances of Bar. The static variable also abides rules for public/private, so you could make it that only instances of Bar can read the value of Bar::a;
Just to add on top of the other answers. In order to initialize a complex static member, you can do it as follows:
Declare your static member as usual.
// myClass.h
class myClass
{
static complexClass s_complex;
//...
};
Make a small function to initialize your class if it's not trivial to do so. This will be called just the one time the static member is initialized. (Note that the copy constructor of complexClass will be used, so it should be well defined).
//class.cpp
#include myClass.h
complexClass initFunction()
{
complexClass c;
c.add(...);
c.compute(...);
c.sort(...);
// Etc.
return c;
}
complexClass myClass::s_complex = initFunction();
If your goal is to initialize the static variable in your header file (instead of a *.cpp file, which you may want if you are sticking to a "header only" idiom), then you can work around the initialization problem by using a template. Templated static variables can be initialized in a header, without causing multiple symbols to be defined.
See here for an example:
Static member initialization in a class template
Optionally, move all your constants to .cpp file without declaration in .h file. Use anonymous namespace to make them invisible beyond the cpp module.
// MyClass.cpp
#include "MyClass.h"
// anonymous namespace
namespace
{
string RE_ANY = "([^\\n]*)";
string RE_ANY_RELUCTANT = "([^\\n]*?)";
}
// member function (static or not)
bool MyClass::foo()
{
// logic that uses constants
return RE_ANY_RELUCTANT.size() > 0;
}