How to initialize private static members in C++?

后端 未结 17 2344
忘掉有多难
忘掉有多难 2020-11-21 07:04

What is the best way to initialize a private, static data member in C++? I tried this in my header file, but it gives me weird linker errors:

class foo
{
           


        
相关标签:
17条回答
  • 2020-11-21 07:26
    int foo::i = 0; 
    

    Is the correct syntax for initializing the variable, but it must go in the source file (.cpp) rather than in the header.

    Because it is a static variable the compiler needs to create only one copy of it. You have to have a line "int foo:i" some where in your code to tell the compiler where to put it otherwise you get a link error. If that is in a header you will get a copy in every file that includes the header, so get multiply defined symbol errors from the linker.

    0 讨论(0)
  • 2020-11-21 07:27

    One "old-school" way to define constants is to replace them by a enum:

    class foo
    {
        private:
            enum {i = 0}; // default type = int
            enum: int64_t {HUGE = 1000000000000}; // may specify another type
    };
    

    This way doesn't require providing a definition, and avoids making the constant lvalue, which can save you some headaches, e.g. when you accidentally ODR-use it.

    0 讨论(0)
  • 2020-11-21 07:28

    I follow the idea from Karl. I like it and now I use it as well. I've changed a little bit the notation and add some functionality

    #include <stdio.h>
    
    class Foo
    {
       public:
    
         int   GetMyStaticValue () const {  return MyStatic();  }
         int & GetMyStaticVar ()         {  return MyStatic();  }
         static bool isMyStatic (int & num) {  return & num == & MyStatic(); }
    
       private:
    
          static int & MyStatic ()
          {
             static int mStatic = 7;
             return mStatic;
          }
    };
    
    int main (int, char **)
    {
       Foo obj;
    
       printf ("mystatic value %d\n", obj.GetMyStaticValue());
       obj.GetMyStaticVar () = 3;
       printf ("mystatic value %d\n", obj.GetMyStaticValue());
    
       int valMyS = obj.GetMyStaticVar ();
       int & iPtr1 = obj.GetMyStaticVar ();
       int & iPtr2 = valMyS;
    
       printf ("is my static %d %d\n", Foo::isMyStatic(iPtr1), Foo::isMyStatic(iPtr2));
    }
    

    this outputs

    mystatic value 7
    mystatic value 3
    is my static 1 0
    
    0 讨论(0)
  • 2020-11-21 07:29

    For a variable:

    foo.h:

    class foo
    {
    private:
        static int i;
    };
    

    foo.cpp:

    int foo::i = 0;
    

    This is because there can only be one instance of foo::i in your program. It's sort of the equivalent of extern int i in a header file and int i in a source file.

    For a constant you can put the value straight in the class declaration:

    class foo
    {
    private:
        static int i;
        const static int a = 42;
    };
    
    0 讨论(0)
  • 2020-11-21 07:31

    You can also include the assignment in the header file if you use header guards. I have used this technique for a C++ library I have created. Another way to achieve the same result is to use static methods. For example...

    class Foo
       {
       public:
         int GetMyStatic() const
         {
           return *MyStatic();
         }
    
       private:
         static int* MyStatic()
         {
           static int mStatic = 0;
           return &mStatic;
         }
       }
    

    The above code has the "bonus" of not requiring a CPP/source file. Again, a method I use for my C++ libraries.

    0 讨论(0)
提交回复
热议问题