我有一个向量和一个在plane.h中声明的对象:
extern Plane Default;
extern std::vector<Plane *>universe;
它们在plane.cpp中定义:
Plane Default("Default");
std::vector<Plane *>universe;
平面构造函数:
Plane::Plane(const std::string &label) {
/* check universe to ensure uniqueness */
std::cout << this << std:endl; //DEBUG CHECK to see what I push_back
universe.push_back(this); //ACTION to keep track of the planes
std::cout << universe.back() << std::endl; //DEBUG CHECK to ensure that it was stored correctly
}
输出确认平面确实存储在矢量中。
主要:
if(universe.empty()) cout << "EMPTY UNIVERSE" << endl;
表示向量未保留该值。我希望Default(在plane.cpp中定义)存储在Universe中。
但是,当我从main
实例化平面时,Universe会保留这些值我想它与本地副本,范围和值传递有关,但我无法找到一种方法来实例化实现中的默认平面,以便它的地址保存在向量中。
我也试过从堆中声明向量,如下所示:
extern std::vector<Plane *> *universe;
并定义如下:
std::vector<Plane *> *universe = new std::vector<Plane *>;
它刚刚破坏了程序。 我在64位Vista机器上使用MinGW32 4.9代码:块16.01和-std = C ++ 11
答案 0 :(得分:5)
您点击全局初始化顺序fiasco:
Plane Default("Default");
std::vector<Plane *>universe;
Default
依赖universe
,但当构造Default
时,universe
尚未构建。
这就是你应该避免全球化的原因。
假设存在相同的翻译单元,您的案例中的解决方法是更改顺序:
std::vector<Plane *>universe;
Plane Default("Default");
答案 1 :(得分:1)
answer by Jarod42应解决您遇到的问题。我将提供一些指导来防止这些问题。
通常,最好避免使用extern
声明变量访问的全局数据。最好使用功能接口提供对全局数据的访问。
您可以更改
extern std::vector<Plane *>universe;
到
extern std::vector<Plane *>& getUniverse();
并将其实施为:
extern std::vector<Plane *>& getUniverse()
{
static std::vector<Plane *>universe;
return universe;
}
有了这个,您可以将Plane
的构造函数更改为:
Plane::Plane(const std::string &label) {
getUniverse().push_back(this);
}
这将消除与全局数据初始化顺序相关的问题。
您也可以更改
extern Plane Default;
到
extern Plane& getDefaultPlane();
并将其实现为
extern Plane& getDefaultPlane()
{
static Plane Default("Default");
return Default;
}
如果必须在初始化时构造默认Plane
,您可以使用以下内容:
// Use a helper struct in an anonymous namespace to initialize
// whatever needs to be initialized.
namespace
{
struct Initializer
{
Initializer();
};
}
// Make sure that Initializer::Initializer() gets called
// at initialization time.
static Initializer initer;
Initializer::Initializer()
{
// Trigger construction of the default Plane
getDefaultPlane();
}
答案 2 :(得分:0)
如果你的指针范围有问题,或许使用shared_ptr就足够了?但是,如果您担心指针的持久性可能被删除或移动并且仍然需要数据,我不知道您的整体设计;一个智能指针可能是答案。如果在任何地方出现循环问题,请使用weak_ptr来打破它。
祝你好运!