i have like 5 erros when trying to compile the code below.
it's like:THey are mainly pointing on static string rzym and static int arab.
the main errors:
In arab2rzym function:
- : invalid use of member ‘RzymArab::arab’ in static member function
- : error: from this location
- : error: invalid use of member ‘RzymArab::arab’ in static member function
- : invalid use of member ‘RzymArab::rzym’ in static member function
- : cannot declare member function ‘static std::string RzymArab::arab2rzym(int)’ to have static linkage [-fpermissive]
Here is the code:
#include <iostream>
#include <string>
using namespace std;
class RzymArab
{
private:
string rzym[13] = {"I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"};
int arab[13] = {1,4,5,9,10,40,50,90,100,400,500,900,1000};
public:
static int rzym2arab(string);
static string arab2rzym(int);
};
static string RzymArab::arab2rzym(int x)
{
int i=12;
string s="";
while(x>=1)
{
if(x>=arab[i])
{
x-=arab[i];
s=s+rzym[i];
}
else
i-=1;
}
return s;
}
int main()
{
string x;
x=RzymArab.arab2rzym(1164);
cout<<x<<endl;
return 0;
}
I would be grateful for helping!I tired some things but still bunch of errors. I want to use elements from class without creating an object.Any ideas?
You can't access non static class member variables from static member functions. You'll need to make them static also:
class RzymArab {
private:
static string rzym[13];
static int arab[13];
public:
static int rzym2arab(string);
static string arab2rzym(int);
};
Also those need to be defined separately (in your class' .cpp file usually):
string RzymArab::rzym[13] =
{"I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"};
int RzymArab::arab[13] = {1,4,5,9,10,40,50,90,100,400,500,900,1000};
Additionally note you don't use the static keyword for the (non inline) definition of your static function (it's invalid syntax). Just write:
string RzymArab::arab2rzym(int x) {
// ...
}
See the fully fixed, compilable and running sample here please.
The deal with class (also known as "static") vs. instance member functions is that an instance member function can access both static and instance members (variables and functions), while static member functions can access only static members. That is why you need to make the
int arab[13]; // The initializer needs to go into cpp file
string rzym[13];
member static in the class:
static int arab[13];
static string rzym[13];
The initializer needs to go to the cpp file:
// This goes into the CPP file
int RzymArab::arab[13] = {1,4,5,9,10,40,50,90,100,400,500,900,1000};
string RzymArab::rzym[13] = {"I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"};
Finally, you refer to static members with the scope resolution operator ::, not with a dot:
x=RzymArab::arab2rzym(1164);
I method that is declared static cannot access data members in the class.
Perhaps you should drop static everywhere?
You cannot access non-static members of a class from a static method of the same class without an object of that class. Non-static members exist only within the context of an object and cannot be access from static methods, that have class scope.
So you either:
make all members static
make all members non-static
pass an object to the static methods used to access the non-static members
Also notice that the static keyword is only necessary when declaring the function, not when you define it.
It isn't possible. A static method can only access other shared things (variables, other methods, etc.).
Example:
Say we have a Square class. You can create an object by passing the height and width into the constructor.
Square mySquare(2,2)
The Square class has a method for getting the area of the object. So you would call it as so:
double area = mySquare.getArea();
That works and all because you are using the instance variables for that specific object's height and width to calculate it. But lets say we want to calculate the area of a square before we create the object to make sure it's valid. So we would call the static getArea(double w, double h) method that is in the Square class.
double area = Square.getArea(2,4);
This works. But if you tried to call the getArea() method (that doesn't have parameters) would give you an error because it wouldn't know what height and width to use because they haven't been defined yet.
double area = Square.getArea(); //This will give you an error.
Hope this helps.
Related
I have not found a way to initialize the class member succesfully inside the constructor and I can not figure out why.
I have a header file:
#pragma once
struct STATE_MOUSE {
bool moving;
int left_button;
int right_button;
int middle_button;
bool scroll_up;
bool scroll_down;
};
class Message {
private:
static STATE_MOUSE state_mouse;
public:
Message();
~Message();
};
Then I have a source file:
#include "message.hpp"
STATE_MOUSE Message::state_mouse = {false, 0, 0, 0, false, false};
Message::Message() {
//Would like to initialize state_mouse here somehow.
}
Message::~Message() {
}
Now to the issue. This set up seems to work. However I am used to initialize members inside a constructor and I have not found a way to do that with this static struct member.
The following method does not work, could someone explain why?
state_mouse.moving = false;
When you declare a member as static it will belong to the class with only one instance and not to the objects of the class, therefore you cannot initialize it inside the constructor. The constructor is a special member function which mainly exists to initialize the non static members of a new object.
Note that a static member is shared by all objects of the class and when an object changes it, the change can be seen from all other objects of the same class. If this is what do you want to achieve, then the method you shown is good.
Static member variables are not associated with each object of the class. It is shared by all objects.
If you declare a static variable inside the class then you should define it in the cpp file, otherwise, you can get error undefined reference.
Note that if the static member variable is of const int type (e.g. int, bool, char), you can then declare and initialize the member variable directly inside the class declaration in the header file.
I know how to access static member variable in static member method - these are two ways I usually use (very simplified):
class S{
private:
static const int testValue = 5;
public:
static int getTestValue0(){
return testValue;
}
static int getTestValue1(){
return S::testValue;
}
};
( working example on : http://ideone.com/VHCSbh )
My question is: is there any more explicit way how to access static member variable than ClassName::staticMemberVar?
Is there something like self:: in C++ ?
...simply I am looking for something like this for referencing static members.
Is there something like self:: in C++ ?
No there is no such feature, but you can use a class local typedef:
class MyClass {
typedef MyClass self;
static int testValue;
static int getTestValue1(){
return self::testValue;
}
};
See a working demo.
There is no support to use something other than class name. You'll need to implement it.
Static Function Members: By declaring a function member as static, you
make it independent of any particular object of the class. A static
member function can be called even if no objects of the class exist
and the static functions are accessed using only the class name and
the scope resolution operator ::.
to read details click here
I have a question about static and static const variable in class.
Especially curious about the memory status about static and static const.
In the following code,
#include <iostream>
using namespace std;
class test{
public:
static const int testConstStatic =1;
static int testStatic;
};
int test::testStatic = 0;
int main(){
cout << test::testStatic << endl;
cout << test::testConstStatic << endl;
return 0;
}
why does 'static int testStatic' need definition to be used and if not, I got 'undefined reference' about testStatic?
Does this definition make linkage about testStatic?
And what about testConstStatic?
Thanks in advance!
UPDATED!!
The main reason of this question was that when I declared static variable as global which surely not defined and printout then no message about 'undefined reference' BUT for the static variable in CLASS without definitino it show the message 'undefined reference'
#include <iostream>
using namespace std;
static int testStaticInGlobal;
class test{
public:
static int testStatic;
};
int test::testStatic = 0;
int main(){
cout << test::testStatic << endl; // 'Undefined reference' error without definition
cout << testStaticInGlobal << endl; // no error without definition
return 0;
}
Thanks!
All variables in C++ must be defined before use. How this definition occurs is dependent on the type of variable.
For non-static class member variables, the definition may be implicitly performed by the class's constructor (which may itself be implicit).
Since static variables, by definition, are not intialized by a constructor, static member variables must always have an explicit definition.
For convenience, C++ allows the definition of a static const member to be combined with its declaration, as you have done, under certain circumstances. Conceptually, the static const int testConstStatic = 1; is doing two distinct things: declaring the testConstStatic member, and defining it to have a value of 1. For whatever reason, the language designers did not choose to allow these two steps to be combined for non-const static members.
Incidentally (to address Ed Heal's comment), a non-static const member (like any non-static member variable) must be defined at construction of object; it will not change after construction is completed, but it may have a different value for each instance of the class, unlike a static const member, which will always have one and only one value for the entire duration of the program.
static const int members are a special case. They're treated as compile-time constants in most usage, and thus a storage location for them isn't required. The only exception is when you try to make a pointer or reference to this variable, then it needs a place to live and you'll need to provide a definition.
static member variable needs to be defined outside the class. That's a rule.
C++11 onwards, const static members usually don't have to be defined outside the class.
Static data members are treated as global variables shared among the object instances, so they ned to be defined once only, and safe bet is outside the class.
const variables are by definition static. So the static in static const is redundant. i.e. just const will do.
The static is required for the static int because without it, the variable is a normal non-static member variable that is only defined for the instance.
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;
}
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;
}