2016-04-29 23 views
2

在我们的项目中,我们使用了外部RAM。当通常调用构造函数时,它在启动时不会被初始化或安全使用。由于这个原因,当一个类需要在外部RAM中实例化时,构造器需要被阻止运行,直到外部RAM准备好使用。这样做的最好方法是什么?推迟C++中的静态变量构造

我能想到的一个选择是为具有正确大小和对齐方式的对象分配一些空间,然后在此位置上调用新放置位置。

static ALTRAM union 
{ 
    UINT64 alignment; 
    UINT8 space[sizeof(ClassName)] 
}spaceHolder; 
ClassName* classInstance = NULL; 
... 
classInstance new (&spaceHolder) ClassName(); 

建议的另一个选项是将对象实例化为传递指向实例的指针的函数中的静态函数对象。我的关注点在于,标准允许在第一次调用函数时调用构造函数,但似乎并不需要所有编译器都这样做。 See bold text from the standard

static ClassName& GetInstance() 
{ 
    static ALTRAM ClassName instance; 
    return instance; 
} 

该项目针对Win32 VC++和Keil for ARM进行编译,但仅对ARM有此要求。是否有编译指示或其他方法来防止构造函数被调用?

我正在寻找不需要修改类的解决方案。

更新

谢谢大家对您的回复也非常有帮助。我得出以下结论:

  1. 体系结构应该在应用程序运行之前初始化硬件。这个问题引发了很多关于我们团队的讨论,它很可能会被修复。
  2. 有些人更喜欢安置新方法。
  3. 对于另一种方法,C++标准要求在第一次执行函数时调用构造函数,所以这应该是可靠和便携的解决方案。
+0

放置新方法有什么问题? – Barmar

+0

操作系统的工作在准备好之前不应该使用这个内存吗?你不应该在操作系统级别而不是应用级别上解决这个问题吗? –

+0

@JesperJuhl是的,操作系统级别的解决方案正在调查中,但还没有。 – colojaro

回答

0

由于已建议,预留的存储和使用位置的新块:

char object[sizeof(ClassName)]; 
new (&object) ClassName(); 
+0

@Quentin - 谢谢。固定。 –

0

如果你关心的编译器被允许建立静态局部对象早于需要,您可以随时添加了一个间接层:支持嵌入式系统配备了C++环境初始化之前要进行初始化一些“启动”示例代码

ClassName &getInstance() { 
    static ClassName *instance(NULL); 
    if(!instance) instance = new ClassName; 
    return *instance; 
} 
+0

有没有办法做到这一点静态分配在外部RAM而不是在堆上? – colojaro

+0

最有可能。例如,您可以使用placement'new'并添加一个预设为true的静态布尔标志:'static ClassName * instance(ADDRESS);静态布尔未定义(true); if(undefined){new(instance)ClassName; undefined = false; }'。 – bipll

0

许多编译器。通常,这段代码设置ARM堆栈寄存器和其他项目。代码可能是汇编语言。你应该把你的内存初始化代码放在这个“启动”代码中。