How to create an element of a static class object?

I am new to C ++, especially in its methods. My question is how can I create an element of a static object of the class itself. I mean, I was declaring a static member object inside the class. Example:

CFoo:CFoo *pFoo[2] = {0}; class CFoo { public: static CFoo *pFoo[2]; public: CFoo(int a); public: CFoo *getFoo(); }; 

Now the problem is how can I create pFoo, for example, I want to create two static pFoo objects,

 pFoo[0] = new CFoo(0); pFoo[1] = new CFoo(1); 

so that I can use the getFoo method to return one of pFoo, for example,

 CFoo *getFoo() { return pFoo[0]; //or pFoo(1); } 

Thanks a lot of guys. I hope my questions are clear.

Thanks in advance. -sasayins

+4
source share
4 answers

Let me improve the code in one step. I will explain what I do at every step.

Step 1, this is not Java. You do not need to specify a publication for each member. Everything after public: is publicly available until you specify something else ( protected or private ). I also moved the definition of pFoo after the class. You cannot define a variable before declaring it.

 class CFoo { public: static CFoo *pFoo[2]; CFoo(int a); CFoo *getFoo(); }; CFoo* CFoo::pFoo[2] = {0}; 

Step 2, pFoo probably should not be public if you have a getFoo member function. Allow you to force an interface to a class, rather than exposing internal data.

 class CFoo { public: CFoo(int a); CFoo *getFoo(); private: static CFoo *pFoo[2]; }; CFoo* CFoo::pFoo[2] = {0}; 

Step 3, you can return with a pointer without bothering to use new . I have written C ++ code for many years, and I will need to see how you delete memory that was entered for the static member variable. It's not worth the hassle to figure it out, so let's just pop them on the stack. Also, return them with a const pointer so that users do not accidentally modify two static CFoo objects.

 class CFoo { public: CFoo(int a); const CFoo *getFoo(); private: static CFoo foos[2]; }; CFoo CFoo::foos[2] = {CFoo(0), CFoo(1)}; 

The getFoo implementation then becomes:

 const CFoo * CFoo::getFoo() { return &foos[0]; // or &foos[1] } 

IIRC, the static member foos will be highlighted the first time you create a CFoo object. So this code ...

 CFoo bar; const CFoo *baz = bar.getFoo(); 

... is safe. A pointer named baz will point to the static member foos[0] .

+20
source

You don't need pointers here. In fact, they are probably not a good idea.

The following code works for me:

 #include <iostream> struct Foo { static Foo const foos[]; Foo(int i) : i(i) { } int i; }; Foo const Foo::foos[2] = { Foo(1), Foo(2) }; using namespace std; int main() { cout << Foo::foos[0].i << endl; } 

(Note that (to keep the demo simple) Ive made all members public , which is probably not the way you want. It works just as well with private members.)

+6
source

To initialize an array, you must write the following:

 CFoo* CFoo::pFoo [2] = { new CFoo(0), new CFoo(1) }; 

Do not free allocated memory this way.

+3
source

There are several ways to do this. One of them is to keep doing what you are doing and initialize the pFoo array, like this

 // In source file (not header) CFoo* CFoo::pFoo[2] = {new CFoo(1), new CFoo(2)}; 

But I would suggest wrapping them in an accessory as follows:

 // In header class CFoo { public: CFoo(int a); CFoo* getFoo1() const; CFoo* getFoo2() const; private: static CFoo* getFoo(int n); }; // In source file CFoo::CFoo(int a) { // Constructor implementation } CFoo* CFoo::getFoo1() const { return getFoo(1); } CFoo* CFoo::getFoo2() const { return getFoo(2); } CFoo* CFoo::getFoo(int n) { static CFoo* pFoo[2] = {new Foo(1), new Foo(2)}; return pFoo[n]; } 

The main reason is that it turns into a fiasco of the static initialization order. When you have a static variable in a class, it is somewhat non-deterministic when it is initialized, which is dangerous, especially when the variable is public. A wrapper in an accessory means that the variable will be initialized when the accessor is first called, and so you will know that it is initialized before you try to use it. In addition, you benefit from lazy initialization if it has not been used for some time or at all.

The code above is not thread safe, but I doubt that you are using threads here.

Also, you should probably consider a coding style. Prefix classes with C are somewhat archaic, and putting "public:" before every public function is fancy, you only need to write it once.

+2
source

All Articles