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

我想要这样的东西。

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

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

ISO c++禁止初始化 “矩形”成员 非整型静态数据成员' std::string '的类内初始化无效 错误:使“矩形”静态

这说明这种构件设计是不符合标准的。如何在不使用#define指令的情况下获得私有文字常量(或者公共常量)(我想避免数据全局的丑陋!)

任何帮助都是感激的。


当前回答

当前标准只允许对静态常量整型进行这样的初始化。所以你需要按照AndreyT解释的去做。但是,这将在下一个标准中通过新的成员初始化语法实现。

其他回答

在类定义内部,只能声明静态成员。它们必须在类之外定义。对于编译时整型常量,标准给出了可以“初始化”成员的例外。但它仍然不是一个定义。例如,如果没有定义,就不能使用地址。

我想提一下,对于常量,我没有看到使用std::string而不是const char[]的好处。string很好,但它需要动态初始化。所以,如果你写

const std::string foo = "hello";

在命名空间范围内,foo的构造函数将在main开始执行之前运行,该构造函数将在堆内存中创建常量“hello”的副本。除非你真的需要RECTANGLE作为std::string,否则你也可以这样写

// class definition with incomplete static member could be in a header file
class A {
    static const char RECTANGLE[];
};

// this needs to be placed in a single translation unit only
const char A::RECTANGLE[] = "rectangle";

在那里!没有堆分配,没有复制,没有动态初始化。

干杯,年代。

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

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

注意,这与深渊不同。7的回答:它定义了一个真正的std::string对象,而不是const char*

当前标准只允许对静态常量整型进行这样的初始化。所以你需要按照AndreyT解释的去做。但是,这将在下一个标准中通过新的成员初始化语法实现。

你必须在类定义之外定义你的静态成员,并在那里提供初始化式。

第一个

// 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";

您最初尝试使用的语法(类定义中的初始化式)只允许整型和枚举类型。


从c++ 17开始,你有另一个选项,这与你最初的声明非常相似:内联变量

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

不需要额外的定义。

这只是额外的信息,但如果你真的想在头文件中使用字符串,可以尝试如下方法:

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

        return str;
    }
};

尽管我怀疑这是否被推荐。