I have read that constructors can inizialize only non static attribute. I have written a small code to check that and Im wondering now because the compiler dosnt show any error??? So Can I initialize static attribute and non static attribute in the constructor or not? this is my code! Thank you very much!
class NixIs {
int var;
static int global;
public:
NixIs(int val = 0)
{
global = val;
}
I think you mean "field" instead of "attribute"
Your code is valid C++ but it does not initialize the static field global, as it's an instance constructor.
If you want to initialize NixIs::global with a trivial constant value (known at compile-time) you can specify it inline in the header:
NixIs.h:
class NixIs {
static int global = 0;
}
If you have a non-constant initial value (such as a parameterless free-function result) then the static field initializer needs to be in a code-file (instead of a header). You need to specify the static field in addition to its type and the initial value of the static field:
NixIs.h:
class NixIs {
static int global;
}
NixIs.cpp:
int NixIs::global = nonTrivialValue;
If you want to initialize multiple static fields in a particular order or with function-result values you'll need to use a hack because C++ does not have static constructors. See here: Static constructor in c++
Initializing an attribute in a constructor is usually done using the initializer list. For instance, you could initialize the non-static attribute in your class like this:
NixIs( int init_val) : val(init_val) {
// do stuff
}
I think that is what you meant. Trying to initialize a static class member like this would be an error. However, all class methods including constructors and destructors can access static members. In your example, 'global' would simply be overwritten with each new instance that is created.
NixIs first(1); // first.global is now 1
NixIs second(2); // first.global is now also 2 (same as second.global)
Related
For example I have a following class:
class singelton
{
public:
static singelton* Instance()
{
if (m_pInstance == 0)
{
m_pInstance = new singelton();
}
return m_pInstance;
}
void setData(std::string input) { data = input; }
void getData() const { std::cout << data << std::endl; }
private:
singelton() {}
~singelton() {}
static singelton* m_pInstance;
std::string data;
};
typedef singelton s;
//what is this? Why need a singleton name? I mean "singelton*".
singelton* singelton::m_pInstance = 0;
int main(int argc, char** argv)
{
s.Instance()->setData("Something...");
s.Instance()->getData();
return 0;
}
What is singelton* singelton::m_pInstance = 0;?
This function assigns zero/null to a singleton instance, but why need use singleton* ? That assignment like a function, but use as assignment.
Static data members are not part of objects of a given class type; they are separate objects. As a result, the declaration of a static data member is not considered a definition. So static member must be defined outside of the class declaration.
In your example:
singelton * is a type of member.
singleton:: is class name (like namespace)
and m_pInstance is member name
P.S.: Because of static variables are initialised with 0 by default in C++, you don't need to explicitly set m_pInstance to 0 (or NULL). The definition only will be enough:
singelton * singelton::m_pInstance;
What is singelton* singelton::m_pInstance = 0;?
It's the initialiser for the static member variable m_pInstance, statically initialising the pointer to be null. singelton* (pointer to singelton) is the type of the variable; singlelton::m_pInstance is the (qualified) name of the variable; and = 0 is the initialiser.
This function assigns zero/null to a singleton instance, but why need use singleton* ?
No, it initialises the pointer to null; it doesn't point to anything yet. The object itself will be created, and the pointer updated to point to it, the first time someone calls Instance(). It's a pointer so that the object itself can be created when it's first needed, rather than at some arbitrary point during program startup - this is known as "lazy initialisation".
Beware that, in C++, there is no way to implement the Singleton anti-pattern correctly. This particular implementation has the problems of leaking the object, and not being thread-safe. I strongly recommend that you get rid of it: just instantiate the object in an appropriate place, with a lifetime that's longer than whatever uses it, and pass references to whatever needs it.
Use
Singleton::Instance()->setData("Hello");
and
Singleton::Instance()->getData();
The class can only have one instance - hence called singleton
And the Singleton::Instance gives you access to that
singelton* singelton::m_pInstance = 0;
Initializes it and when you first use it the singleton is created
So far I have used DEFINE to declare my constants. and it works perfectly fine.
I am trying to use the c++ const keyword in my classes but it gives compile time error
Header
class User{
public:
User::User();
protected:
const float DATA_Z;
}
.CPP
User::User(){
DATA_Z = 0.0023f;
}
this is the error it generates
Error 3 error C2758: 'User::DATA_Z ' : must be initialized in constructor base/member initializer list
How can I assign a data to it, and how can I use them in my class.
The error message is pretty clear. Move assignment into initializer list:
User::User(): DATA_Z(0.0023f)
{
}
You want to do this instead:
User::User() : DATA_Z(0.0023f)
{
// body of constructor
}
Constant members need to be initialized in the initializer list, because they cannot be assigned directly. The same is also true for members that are reference-type, because you cannot change the referent of a reference variable.
To simply replace manifest constants defined with #define, write global consts:
#define DATA_Z 0.0023f
becomes
const float DATA_Z = 0.0023f;
Putting the constants into the class means you can have a different value in each object, which is why the other answers tell you to initialize it in the constructor. That's a legitimate design decision, but it's different from defining the value as a macro.
The following code helps you to pass any value to initialize the DATA_Z:
`
class User{
public:
User::User(float data=0):DATA_Z(data){}; // here `data` is a local parameter to receive the assigned value.
protected:
const float DATA_Z;
}
`
When we declare some variable inside class or struct in C/C++, we have to make an object of class or struct to allocate memory for the variable.
Why can't we just access these variables without any object?
Well, the answer is really: because that's the whole point of this language feature. The very idea of a data member of a class is for it to be an integral part of class object. It begins its life together with the entire class object and it ends its life together.
If you have two class objects, you have two completely independent sets of data members. If you have 50 class objects, you have 50 completely independent sets of data members. If you have zero class objects, you have no sets of data members to access. In other words, you cannot access these "variables" without a class object simply because they do not exist without a class object.
You are not really "declaring a variable" when you declaring a data member of a class in a class definition. Class definition simply describes the layout of class type. By itself it produces nothing physical, i.e noting that would live in data memory, noting you can physically access.
Meanwhile, C++ language has such concept as static member of the class. Static data members of the class are not associated with specific class objects. They exist independently. In fact, static data members are just ordinary global variables covered by a fairly thin layer of C++-specific "syntactic sugar" (more elaborate naming, access control etc.) Static data members of the class can be accessed as ordinary variables, without any object.
In other words, it is not a question of "why?" but rather a question of what you need. If you want non-static data member functionality, use non-static data members. If you want static data member functionality... well, you get the idea.
A class is just a 'layout' used to specify how instanced object will be constructed, destroyed and how they will behave. For an imaged comparizon with buildings: a class is the plan used to build the house. The object is the house itself.
If you want variable without objects, use global variables. You can put them in a namespace:
namespace test
{
int answer = 42; // Initialization is optional
}
// ...
void f()
{
// Use it like this:
test::answer = 0;
}
You can also use static members:
class MyClass
{
public:
static int value;
};
Usually, you declare a member variable inside a class precisely because you want it to be part of an object of that class type. That's what that language feature is for: to allow you to have many distinct objects, each with its own state independent of any other object.
In C++ (but not C), you can declare it static if you want a single variable, independent of any object. This will have static storage duration, just like a variable declared outside a class. In C, global variables are the only option if you want something like this.
For example:
struct thing {
int a; // part of a "thing" object
static int b; // not part of a "thing"
};
// Static variables need a definition, in exactly one source file
int thing::b;
int main() {
thing::b = 1; // OK: no object needed
thing::a = 2; // ERROR: object needed
thing t1;
t1.a = 3; // OK: accessing object member
t1.b = 4; // OK: equivalent to "thing::b"
thing t2;
t2.a = 5; // OK: accessing object member
t2.b = 6; // OK: equivalent to "thing::b"
std::cout << t1.a; // prints 3
std::cout << t2.a; // prints 5 - independent of t1.a
std::cout << t1.b; // prints 6
std::cout << t2.b; // prints 6 - same variable as t1.b (aka thing::b)
}
Using the static keyword:
class A {
public:
static int varaible;
};
int A::variable = 5;
Then you can access the variable without an object anytime. As follows.
A::varaible = 25;
Things you'll need to know:
You will need to use the scope operator(::) to access a static member.
Definition of a static member must be done outside of the class. The above statement int A::variable = 5; is an definition of a static member.
All objects of type A (included inherited objects) share a static member. [1]
[1]
A a;
A b;
a::variable == b::variable == 25;
//if we change a::variable
a::variable = 26;
//b::variable has the same value.
b::variable == a::variable == 26;
I am learning C++ by making a small robot simulation and I'm having trouble with static member functions inside classes.
I have my Environment class defined like this:
class Environment {
private:
int numOfRobots;
int numOfObstacles;
static void display(); // Displays all initialized objects on the screen
public:
Robot *robots;
Obstacle *obstacles;
// constructor
Environment();
static void processKeySpecialUp(int, int, int); // Processes the keyboard events
};
Then in the constructor I initialize the robots and obstacles like this:
numOfRobots = 1; // How many robots to draw
numOfObstacles = 1;
robots = new Robot[numOfRobots];
obstacles = new Obstacle[numOfObstacles];
Here is example of static function that uses those variables:
void Environment::display(void) {
// Draw all robots
for (int i=0; i<numOfRobots; i++) {
robots[i].draw();
}
}
When I try to compile, I get error messages like
error: invalid use of member ‘Environment::robots’ in static member function
I tried making numOfRobots, numOfObstacles, robots and obstacles static, but then I got errors like
error: undefined reference to 'Environment::numOfRobots'
I would greatly appreciate of someone could explain me what I am doing wrong.
Thank you!
Static methods can't use non-static variables from its class.
That's because a static method can be called like Environment::display() without a class instance, which makes any non-static variable used inside of it, irregular, that is, they don't have a parent object.
You should consider why you are trying to use a static member for this purpose. Basically, one example of how a static method can be used is as such:
class Environment
{
private:
static int maxRobots;
public:
static void setMaxRobots(int max)
{
maxRobots = max;
}
void printMaxRobots();
};
void Environment::printMaxRobots()
{
std::cout << maxRobots;
}
And you would have to initialize on the global scope the variables, like:
int Environment::maxRobots = 0;
Then, inside main for example, you could use:
Environment::setMaxRobots(5);
Environment *env = new Environment;
env->printMaxRobots();
delete env;
There are 2 issues here - the algorithm you're trying to implement and the mechanics of why it won't compile.
Why it doesn't compile.
You're mixing static and instance variables/methods - which is fine. But you can't refer to an instance variable from within a static method. That's the "invalid use" error. If you think about it, it makes sense. There is only one "static void display()" method. So if it tries to refer to the non-static (instance) variable "robots", which one is it referring to? There could be 10 ... or none.
The logic you are trying to implement.
It looks like you want a single Environment class that manages N robots. That's perfectly logical. One common approach is to make Environment a 'singleton' - an instance variable that only allows for a single instance. Then it could allocate as many robots as it want and refer to them freely because there are no static variables/methods.
Another approach is to just go ahead and make the entire Environment class static. Then keep a (static) list of robots. But I think most people these days would say option #1 is the way to go.
static members are those that using them require no instantiation, so they don't have this, since this require instantiation:
class foo {
public
void test() {
n = 10; // this is actually this->n = 10
}
static void static_test() {
n = 10; // error, since we don't have a this in static function
}
private:
int n;
};
As you see you can't call an instance function or use an instance member inside an static function. So a function should be static if its operation do not depend on instance and if you require an action in your function that require this, you must think why I call this function static while it require this.
A member variable is static if it should shared between all instances of a class and it does not belong to any specific class instance, for example I may want to have a counter of created instances of my class:
// with_counter.h
class with_counter {
private:
static int counter; // This is just declaration of my variable
public:
with_counter() {++counter;}
~with_counter() {--counter;}
static int alive_instances() {
// this action require no instance, so it can be static
return counter;
}
};
// with_counter.cpp
int with_counter::counter = 0; // instantiate static member and initialize it here
The first error says that you cannot use non-static members in static member functions.
The second one says that you need to define static members in addition to declaring them You must define static member variables outside of a class, in a source file (not in the header) like this:
int Environment::numOfRobots = 0;
You don't need any static members. To have an absolutely correct and portable GLUT interface, have a file-level object of type Environment and a file-level (non-member) function declared with C linkage. For convenience, have also a member function named display.
class Environment
{
public:
void display() { ... }
...
};
static Environment env;
extern "C" void display () { env.display(); }
A static member function is one that can be called without an actual object of that kind. However, your function Environment::display uses the variables numOfRobots and robots, which both live in a particular instance of the Environment class. Either make display non-static (why do you want it to be static?) or make the robots static members of Environment too.
In your case, I don't see a reason for making display or processKeySpecialUp static, so just make them normal member functions. If you wonder when a member function should be static, consider if that function would make sense if no objects of that class have been created (i.e. no constructors been called). If the function doesn't make sense in this context, then it shouldn't be static.
A static method cannot access instance variables. If you want to access instance variable remove static from the method. If those values can be the same through all robot instances then make them static variables and the method can remain static.
if you want to access member variables in static member function just create a static pointer of the member variable and use it in the function !!!!!
Hi I was trying to define a constant inside a class, doing it the normal or usual way doesnt seem to work
class cat
{
public:
cat();
~cat();
private:
static const int MAX_VALUE = -99999;
int Number;
public:
void OrganizeNumbers();
void SetNumbers();
};
So the solution I found after doing some research was to declare it as static but what does this means and also I want to ask it is really necesary to declare a constant, becuase as you can see it is private right? i means it can only be accessed by the class methods so why to set a constant and also I read that using static only allows you to use integral type so its actually a dissavantage... if you are thinking to make a game.
static means that the member will be shared across all instances of your object.
If you'd like to be able to have different values of a const member in different instances you'll need to use a initialization list to set it's value inside your constructor.
See the following example:
#include <string>
struct Person {
Person (std::string const& n)
: name (n)
{
// doing: 'name = n' here is invalid
}
std::string const name;
};
int main (int argc, char *argv[]) {
Person a ("Santa Claus");
Person b ("Bunny the Rabbit");
}
Further reading
[10] Constructors - parashift.com/cpp-faq
10.1 Construct Initialization List
Initialization Lists in C++
1) Declare it "private" if you're only going to use MAX_VALUE inside your class's implementation, declare it under "public" if it's part of your class's interface.
2) Back in "C" days, "static" was used to "hide" a variable from external modules.
There's no longer any need to do this under C++.
The only reason to use "static" in C++ is to make the member class-wide (instead of per-object instance). That's not the case here - you don't need "static".
3) The "const" should be sufficient for you.
4) An (older-fashioned) alternative is to define a C++ enum (instead of a "const int")
There seems to be some confusion of ideas here:
A static member doesn't have to be an integral type, the disadvantage you mention does not exist.
const and private are unrelated, just because a member can only be accessed from instances of a given class, doesn't mean that nothing is going to change it.
Being const-correct guards against runtime errors that may be caused by a value changing unexpectedly.
you have to init the const attribute in the constructor with :
cat() : MAX_VALUE(-99999) {}
(which was declare as const int MAX_VALUE;)