在全球范围内调用new new

时间:2011-11-10 09:50:26

标签: c++ new-operator

一位同事和我正在争论在全球范围内撰写本文的可编辑性:

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没有。那段时间不那么惊讶。)

虽然这对我来说是非常错误的(没有有条理/正确的方式/时间来调用删除), 它不是编译器禁止的。为什么呢?

3 个答案:

答案 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函数属性(这可能有助于订购)。