为什么GCC 4.7在实例化函数内的一个类(带指针)时会抱怨?
为:
#include "foo.h"
int fn () {
Foo *foo;
foo->method();
return 0;
}
main.cpp:在成员函数'int foo()'中: main.cpp:21:52:警告:'fn'可以在这里使用未初始化 功能[-Wuninitialized]
好:
#include "foo.h"
Foo *foo;
int fn () {
foo->method();
return 0;
}
好:
#include "foo.h"
int fn () {
Foo foo;
foo.method();
return 0;
}
答案 0 :(得分:6)
Foo * foo;
和Foo foo;
之间存在差异。第一个向Foo声明指针,第二个声明&调用Foo的默认构造函数。
编辑:也许你打算编写Foo * foo= new Foo();
,以便在堆上分配一个Foo
,它可以比函数调用更长。
答案 1 :(得分:5)
第一个(坏),foo指向垃圾指针。您可以通过像Foo* foo = NULL;
那样初始化来删除警告,但是当您尝试取消引用它时会出现错误(运行时错误)。
第二个(好的)没有抱怨,因为C自动将翻译单元范围中的变量初始化为NULL或0或者如果它们尚未初始化则适当的等效。
最后一个(好的)没有抱怨,因为你在对象上调用一个方法,并且函数指针的赋值由编译器完成,与数字2类似但不相同。所以编译器已经知道了方法method
的地址,并已将该地址分配到Foo
结构上的适当位置。
答案 2 :(得分:2)
Foo* foo; foo->method()
从不 好。 foo
是一个未初始化的指针,可能指向垃圾,因此您的代码显示未定义的行为。您可能希望的 best 是编译器警告或错误。如果没有,那么至少希望运行的程序崩溃。
答案 3 :(得分:2)
在您的错误示例中,foo
是一个具有指针类型的局部变量,它不会自动初始化。正确示例中的class Foo
是使用默认构造函数初始化的。
您的第一个“好”示例使用0
初始化指针,因为foo
是一个全局变量。它将在运行时导致未定义的行为,因为foo
未指向对象。
答案 4 :(得分:2)
因为正如警告所说,它是未初始化的。还没有任何对象。实际上你的第一个例子中foo的值是未定义的。它将具有驻留在foo所在的内存中的值。
澄清一下,foo(你看作Foo *)实际上是一个int。 int的值应该是Foo类型对象的地址。要做到这一点,你必须为它指定一个foo的地址。其中一个是用new:
实例化它Foo* foo = new Foo;
new
返回创建新Foo对象的地址。这将删除你的警告:)