是否可以通过其他类中的另一个const静态字段来初始化const静态字段?

问题描述

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

一个简化的示例中:

// 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相互依赖的字段有更好的设计策略?

解决方法

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

此外,在您给出的示例中,您需要将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 };
};