I'm trying to initialize the state of my static const
field from (a part of) the state of another const static
field from a different class in a different file.
In a simplified example:
// 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 };
In my experience, I found that B::o
could not initialize from A::o
. It compiles, but the std::string B::o
is empty. Am I doing something wrong, or is this simply not possible? Or are there better design strategies for static const
fields relying on each other?
From C++17 onwards, you can use inline
member variables - in the class declarations - in the respective header files. This avoids the need for definitions of those members in individual source files, thus avoiding any ambiguities related to the order of evaluation of different translation units.
Also, in the example you've given, you'll need to make the A::o
a public
member, in order for the B
class to use it (class members are private
by default).
Here's a possible 'header-only' solution to your problem:
// 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 };
};