new Foo 和 new Foo()的区别以及Foo f2()的问题

来源:互联网 发布:淘宝助理没有销售属性 编辑:程序博客网 时间:2024/05/22 15:36

new Foo 和 new Foo()的区别:

问题是:在C++中,以下两者有何不同

  1. new Foo;
  2. new Foo();

两者都是正确的语句,它们都返回一个指针,指向新创建的Foo(存放在堆中)。但是,当Foo是POD类型时,它们的表现有所不同。

PS:POD类型是指一个类或对象,其成员是原生数值类型(int, unsigned char, float, bool等等)或者另外一个POD类型。POD对象看起来像C语言风格的结构对象,例如:

// PODclass Foo {    public:         int a;};// NOT a podclass Bar {    public:        int a;        string name; // not a POD type};
//PODclass Bar {    public:    int a;    Bar* str;};

当Foo是POD类型时,new Foo不会初始化,而new Foo()会将成员初始化为默认值,示例如下:

struct Foo {    int a;};int main() {    Foo* foo = new Foo;    foo->a = 7;    delete foo;    Foo* new_foo = new Foo;   <pre name="code" class="cpp" style="font-size: 12.727272033691406px; line-height: 18.99147605895996px;">    cout << new_foo->a << endl;
delete new_foo; return 0;}

a值将为不定值,编译器不同结果不同。在VS中为-842150451

struct Foo {    int a;};int main() {    Foo* foo = new Foo();    foo->a = 7;    delete foo;    Foo* new_foo = new Foo(); <pre name="code" class="cpp" style="font-size: 12.727272033691406px; line-height: 18.99147605895996px;">    cout << new_foo->a << endl;
delete new_foo; return 0;}

a值将初始化为0

当Foo不是POD类型时,new Foo,new Foo()都不会初始化,示例如下:

class Bar {    public:    int a;//Bar* str;    string name; // not a POD type};int main() {    Bar* foo = new Bar;    foo->a = 7;    delete foo;    Bar* new_foo = new Bar;    cout << new_foo->a << endl;    delete new_foo;    Bar* foo1 = new Bar();    foo1->a = 7;    delete foo1;    Bar* new_foo1 = new Bar();    cout << new_foo1->a << endl;    delete new_foo1;    return 0;}
VS中输入结果都为-842150451

Foo f2()的问题:

问题:一个拥有默认构造函数的类,当在栈上构造该类的一个实例时,变量名后面需不需要加一对空括号?

答案:不需要、也不能加空括号

如果紧接着追问下去:如果加了空括号,会有什么后果?编译器是报一个错误还是让它顺利通过编译?

从语法上讲,加了空括号并没有错误,这是一条完全符合语法的语句,示例如下:

class Foo {    public:        void execute();    };    int main() {     Foo f1;         //在栈上构造一个Foo对象的实例,名为f1     Foo f2();       //完全正确的语法:声明一个函数原型,它没有参数,并且返回一个Foo的实例     f1.execute();     f2.execute();   //编译错误}

上面这段示例代码,Foo f2(); 是声明了一个函数原型。那么编译器会给出一个警告,它认为你声明了一个函数原型,但没有使用这个函数;如果加上f2.execute();则编译器会报一个编译错误,原因很明显:f2只是一个函数名,而不是类、结构或联合(的实例)。


0 0