这是旧主题的另一种变体:初始化顺序 未定义不同翻译单元中的静态对象。
下面是我特定场景的精简示例。该 G和F类是非POD类型。 F取决于G是指的意义 构造一个F的实例,你需要一些实例 G.(例如,F可能是应用程序发出的一些消息,并且 G的实例将是此类消息的组成部分。)
G.hpp
#ifndef G_HPP
#define G_HPP
struct G
{
G() {} // ...
};
inline G operator+(G, G) { return G(); }
#endif
Gs.hpp
#ifndef GS_HPP
#define GS_HPP
#include "G.hpp"
extern const G g1;
extern const G g2;
extern const G g3;
extern const G g4;
extern const G g5;
extern const G g6;
extern const G g7;
extern const G g8;
extern const G g9;
#endif
Gs.cpp
#include "Gs.hpp"
const G g1;
const G g2;
const G g3;
const G g4;
const G g5;
const G g6;
const G g7;
const G g8;
const G g9;
F.hpp
#ifndef F_HPP
#define F_HPP
#include "G.hpp"
struct F
{
F(G) {} // ...
};
#endif
Fs.hpp
#ifndef FS_HPP
#define FS_HPP
#include "F.hpp"
extern const F f1;
extern const F f2;
extern const F f3;
#endif
Fs.cpp
#include "Fs.hpp"
#include "Gs.hpp"
const F f1(g1 + g2 + g3);
const F f2(g4 + g5 + g6);
const F f3(g7 + g8 + g9);
F的构造函数接受一个参数,该参数是应用的结果
operator+
到G的实例。因为F和G的实例都是
全局变量,不能保证G的实例有
当F的构造函数需要它们时被初始化。
这里的特殊之处在于,有很多Gs和Fs 地方,我想保持语法尽可能接近 到上面发布的代码,同时仍然执行一个 G只要F需要它。
答案 0 :(得分:1)
来自http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.15。
将全局对象更改为在首次使用时构造对象的函数。
// Gs.hpp
const G & g1();
// Gs.cpp
const G & g1() {
static const G* g1_ptr = new G();
return *g1_ptr;
}
// Fs.cpp
const F & f1() {
static const F* f1_ptr = new F(g1() + g2() + g3());
return *f1_ptr;
}
或者如果您真的无法添加额外的()
,请使用一些#define
来隐藏它们:
// Gs.hpp
const G & get_g1();
#define g1 (get_g1())
// Definition of get_g1() like g1() from prev. example
答案 1 :(得分:0)
在标题中保留extern声明。将所有fN
和gN
定义以适当的顺序放入单个cpp文件中。
答案 2 :(得分:0)
也许类似于用于初始化cin
和朋友的文件缓冲区的技巧会对你有用吗? (仔细阅读<iostream>
。)