c++ - 静态类 - static const类内初始化




C++静态常量字符串(类成员) (7)

要使用该类内初始化语法,该常量必须是由常量表达式初始化的整型或枚举类型的静态常量。

这是限制。 因此,在这种情况下,您需要在课程外定义变量。 请参阅@AndreyT的答案

我想要一个类的私有静态常量(在这种情况下是一个形状工厂)。 我想有这样的事情。

class A {
   private:
      static const string RECTANGLE = "rectangle";
}

不幸的是,我得到了C ++(g ++)编译器的各种错误,比如:

ISO C ++禁止成员'RECTANGLE'的初始化

非整型类型'std :: string'的静态数据成员的无效类内初始化

错误:使'RECTANGLE'静态

这告诉我这种成员设计不符合标准。 你如何拥有一个私有字面常量(或者也许是公共的)而不必使用#define指令(我想避免数据全局性的丑陋!)

任何帮助表示赞赏。 谢谢。


你可以选择上面提到的const char*解决方案,但是如果你总是需要string,那么你将会有很多开销。
另一方面,静态字符串需要动态初始化,因此如果你想在另一个全局/静态变量的初始化期间使用它的值,你可能会遇到初始化顺序的问题。 为了避免这种情况,最便宜的是通过getter访问静态字符串对象,该对象检查对象是否被初始化。

//in a header  
class A{  
  static string s;   
public:   
  static string getS();  
};  
//in implementation  
string A::s;  
namespace{  
  bool init_A_s(){  
    A::s = string("foo");   
    return true;  
  }  
  bool A_s_initialized = init_A_s();  
}  
string A::getS(){      
  if (!A_s_initialized)  
    A_s_initialized = init_A_s();  
  return s;  
}  

请记住只使用A::getS() 。 因为任何线程只能由main()启动,并且A_s_initializedmain()之前初始化,所以即使在多线程环境中也不需要锁定。 默认情况下(动态初始化之前) A_s_initialized为0,因此如果在s初始化之前使用getS() ,则可以安全地调用init函数。

顺便说一句,在上面的答案:“ static const std :: string RECTANGLE()const ”,静态函数不能是const因为如果有任何对象(没有这个指针)它们不能改变状态。


在C ++ 11中,你现在可以做到:

class A {
 private:
  static constexpr const char* STRING = "some useful string constant";
};

在C ++ 17中,你可以使用内联变量

class A {
 private:
  static inline const std::string my_string = "some useful string constant";
};

请注意,这是不同于深渊的。7的答案 :这一个定义了一个实际的std::string对象,而不是一个const char*


您必须在类定义之外定义静态成员,并在其中提供初始化程序。

第一

// In a header file (if it is in a header file in your case)
class A {   
private:      
  static const string RECTANGLE;
};

接着

// In one of the implementation files
const string A::RECTANGLE = "rectangle";

您最初尝试使用的语法(类定义内的初始值设定项)只允许使用整型和枚举类型。


目前的标准只允许静态常数整型的初始化。 所以你需要像安德烈解释的那样去做。 但是,这将通过新成员初始化语法在下一个标准中提供。


这只是额外的信息,但如果你真的想要在头文件中的字符串,请尝试如下所示:

class foo
{
public:
    static const std::string& RECTANGLE(void)
    {
        static const std::string str = "rectangle";

        return str;
    }
};

虽然我怀疑这是建议。





const