【问题标题】:Is there a way to initialize a const static field from another const static field in a different class?有没有办法从不同类中的另一个 const 静态字段初始化 const 静态字段?
【发布时间】:2020-10-15 10:23:30
【问题描述】:

我正在尝试从不同文件中不同类的另一个 const static 字段的状态(的一部分)初始化我的 static const 字段的状态。

在一个简化的例子中:

// object.h
class Object {
public:
  Object(std::string s) 
    : s(s)
  {}
private:
  std::string s;
};

// a.h
#include "object.h"
class A {
public:
  static const Object o;
};

// a.cpp
#include "a.h"
const Object A::o { "ObjectToCopyFrom" };

// b.h
#include "object.h"
class B {
public:
  static const Object o;
}

// b.cpp
#include "a.h"
const Object B::o { A::o };

根据我的经验,我发现B::o 无法从A::o 初始化。它可以编译,但 std::string B::o 是空的。我做错了什么,或者这根本不可能?或者static const字段相互依赖有没有更好的设计策略?

【问题讨论】:

  • 请对静态初始化命令失败做一些研究。 static 对象的初始化顺序在 translation units 之间是不确定的。
  • “或者对于相互依赖的静态 const 字段有更好的设计策略吗?” 当然,完全移除依赖并在单独的命名空间/类中定义它们,两者都是A 类和 B 类依赖。
  • @Someprogrammerdude 谢谢你的信息,我会的。我想我在翻译单元方面还有一些工作要做。
  • @AdrianMole 谢谢这正是我想要的,很高兴看到这在更新的 c++ 中是可能的!

标签: c++ static initialization constants field


【解决方案1】:

从 C++17 开始,您可以使用 inline 成员变量 - 在类 declarations 中 - 在相应的 header 文件中。这避免了在单独的 文件中定义这些成员的需要,从而避免了与不同翻译单元的评估顺序相关的任何歧义。

此外,在您给出的示例中,您需要将 A::o 设为 public 成员,以便 B 类使用它(默认情况下,类成员为 private) .

对于您的问题,这是一个可能的“仅标题”解决方案:

// object.h
#include <string>
class Object {
public:
    Object(std::string s_arg) // IMHO, using argument names same as members is not a good idea!
        : s(s_arg)
    { }
private:
    std::string s;
};

// a.h
#include "object.h"
class A {
public: // The "o" member MUST be public in order for the initialization in "B" to work!
    static inline const Object o{ "ObjectToCopyFrom" };
};

// b.h
#include "a.h" // Need to include the "a.h" header to get the definition of "class A"
class B {
    static inline const Object o{ A::o };
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-27
    • 2017-03-04
    • 2016-11-30
    • 2010-12-02
    • 2012-01-01
    相关资源
    最近更新 更多