一位同事和我正在争论在全球范围内撰写本文的可编辑性:
int* g_pMyInt = new int;
我的论点围绕着调用函数(new
是)的事实。
在全球范围内是不可能的。令我惊讶的是,上面的编译就好了
(MS-VC8和Apple的LLVM 3)。
所以我继续尝试:
int* foo()
{
return new int;
}
int* g_pMyInt = foo(); // Still global scope.
并且,编译也是如此,并且像魅力一样工作(稍后在课堂上测试 whos构造函数/析构函数打印出一条消息。 ctor的消息 经过,dtor没有。那段时间不那么惊讶。)
虽然这对我来说是非常错误的(没有有条理/正确的方式/时间来调用删除), 它不是编译器禁止的。为什么呢?
答案 0 :(得分:6)
为什么不应该被允许?您所做的只是初始化一个全局变量,非常欢迎您这样做,即使初始化涉及函数调用:
int i = 5 + 6;
double j(std::sin(1.25));
const Foo k = get_my_foo_on(i, 11, true);
std::ostream & os(std::cout << "hello world\n");
int * p(new int); // fine but very last-century
std::unique_ptr<int> q(new int); // ah, welcome to the real world
int main() { /* ... */ }
当然,您需要担心删除动态分配的对象,无论它们是否在全局范围内分配......拥有资源的包装类(如unique_ptr
)将是理想的解决方案。
答案 1 :(得分:2)
当然,您可以从全局范围调用函数,作为全局对象初始化的一部分。如果不能,则无法使用构造函数定义类型的全局变量,因为构造函数也是函数。但请注意,不同翻译单元之间的初始化顺序没有很好地定义,因此如果您的函数依赖于来自另一个翻译单元的全局变量,除非您采取特殊预防措施,否则您将遇到麻烦。
答案 2 :(得分:2)
C ++允许在main
函数之前和之后进行处理,特别是对于具有构造函数和放大器的静态对象。析构函数(它们的构造函数必须在main
之前运行,它们之后是析构函数)。实际上,执行顺序没有明确定义。
如果您正在使用GCC,请参阅其constructor函数属性(这可能有助于订购)。