如果'Test'是一个普通类,那么以下两者之间是否有区别:
Test* test = new Test;
and
Test* test = new Test();
如果'Test'是一个普通类,那么以下两者之间是否有区别:
Test* test = new Test;
and
Test* test = new Test();
当前回答
不,它们是一样的。但两者之间是有区别的:
Test t; // create a Test called t
and
Test t(); // declare a function called t which returns a Test
这是因为c++(和C)的基本规则:如果某个东西可以是声明,那么它就是声明。
编辑:关于POD和非POD数据的初始化问题,虽然我同意已经说过的一切,但我只是想指出,这些问题只适用于新构造的东西或其他构造方法没有用户定义的构造函数。如果有这样的构造函数,将使用它。99.99%的合理设计的类都有这样的构造函数,因此可以忽略这个问题。
其他回答
一般来说,第一种情况是默认初始化,第二种情况是值初始化。
例如: 如果是int (POD类型):
Int *test = new Int -我们有任意的初始化,*test的值可以是任意的。 Int *test = new Int () - *test的值为0。
接下来的行为取决于你的测试类型。 我们有不同的情况:测试有默认构造函数,测试生成默认构造函数,测试包含POD成员,非POD成员…
假设Test是一个定义了构造函数的类,没有区别。后一种形式更清楚地表明Test的构造函数正在运行,但仅此而已。
新事物();是显式的,你想要一个构造函数调用while new Thing;表示您不介意不调用构造函数。
如果在带有用户定义构造函数的结构/类上使用,则没有区别。如果在一个普通的struct/类上调用(例如struct Thing {int i;};)然后new Thing;是像malloc(大小(东西));而new Thing();是像calloc(sizeof(Thing));-它得到零初始化。
问题就在这两者之间:
struct Thingy {
~Thingy(); // No-longer a trivial class
virtual WaxOn();
int i;
};
新事物的行为;vs new Thingy();在这种情况下,在c++ 98和c++ 2003之间变化。详见Michael Burr的解释。
我在下面写了一些示例代码,作为Michael Burr回答的补充:
#include <iostream>
struct A1 {
int i;
int j;
};
struct B {
int k;
B() : k(4) {}
B(int k_) : k(k_) {}
};
struct A2 {
int i;
int j;
B b;
};
struct A3 {
int i;
int j;
B b;
A3() : i(1), j(2), b(5) {}
A3(int i_, int j_, B b_): i(i_), j(j_), b(b_) {}
};
int main() {
{
std::cout << "Case#1: POD without ()\n";
A1 a1 = {1, 2};
std::cout << a1.i << " " << a1.j << std::endl;
A1* a = new (&a1) A1;
std::cout << a->i << " " << a->j << std::endl;
}
{
std::cout << "Case#2: POD with ()\n";
A1 a1 = {1, 2};
std::cout << a1.i << " " << a1.j << std::endl;
A1* a = new (&a1) A1();
std::cout << a->i << " " << a->j << std::endl;
}
{
std::cout << "Case#3: non-POD without ()\n";
A2 a1 = {1, 2, {3}};
std::cout << a1.i << " " << a1.j << " " << a1.b.k << std::endl;
A2* a = new (&a1) A2;
std::cout << a->i << " " << a->j << " " << a->b.k << std::endl;
}
{
std::cout << "Case#4: non-POD with ()\n";
A2 a1 = {1, 2, {3}};
std::cout << a1.i << " " << a1.j << " " << a1.b.k << std::endl;
A2* a = new (&a1) A2();
std::cout << a->i << " " << a->j << " " << a1.b.k << std::endl;
}
{
std::cout << "Case#5: user-defined-ctor class without ()\n";
A3 a1 = {11, 22, {33}};
std::cout << a1.i << " " << a1.j << " " << a1.b.k << std::endl;
A3* a = new (&a1) A3;
std::cout << a->i << " " << a->j << " " << a->b.k << std::endl;
}
{
std::cout << "Case#6: user-defined-ctor class with ()\n";
A3 a1 = {11, 22, {33}};
std::cout << a1.i << " " << a1.j << " " << a1.b.k << std::endl;
A3* a = new (&a1) A3();
std::cout << a->i << " " << a->j << " " << a1.b.k << std::endl;
}
return 0;
}
/*
output with GCC11.1(C++20)
Case#1: POD without ()
1 2
1 2
Case#2: POD with ()
1 2
0 0
Case#3: non-POD without ()
1 2 3
1 2 4
Case#4: non-POD with ()
1 2 3
0 0 4
Case#5: user-defined-ctor class without ()
11 22 33
1 2 5
Case#6: user-defined-ctor class with ()
11 22 33
1 2 5
*/
不,它们是一样的。但两者之间是有区别的:
Test t; // create a Test called t
and
Test t(); // declare a function called t which returns a Test
这是因为c++(和C)的基本规则:如果某个东西可以是声明,那么它就是声明。
编辑:关于POD和非POD数据的初始化问题,虽然我同意已经说过的一切,但我只是想指出,这些问题只适用于新构造的东西或其他构造方法没有用户定义的构造函数。如果有这样的构造函数,将使用它。99.99%的合理设计的类都有这样的构造函数,因此可以忽略这个问题。