以下两种创建对象的方法有什么区别?
Test* t = new Test();
和
Test* t;
你对第二个样本的回答与我的想法相匹配(没有创建对象)但是
class Test {
public:
void bla(void) {
std::cout << "test" << std::endl;
};
};
int main(void) {
Test* test;
test->bla();
}
给我输出“test”......所以实际上有一个Object
答案 0 :(得分:7)
第一个做4件事:
Test
Test
个对象(注意,它是Test
,而不是test
)()
- 有关详细信息,请参阅Do the parentheses after the type name make a difference with new? 第二个只是创建指向Test
的指针。而且它没有初始化。
@yogi - 用于编辑 - 这完全是未定义的行为,因为指针未初始化。不,它是不是一个对象。有关详细信息,请参阅C++ function called without object initialization。
答案 1 :(得分:4)
第二个根本不会创建任何对象,并且尝试访问它将导致Bad Things™。
答案 2 :(得分:2)
这是一个指针,分配在堆栈上,使用32或64位内存。
Test * t;
这将在堆上创建一个Test类型的对象(你需要对它进行脱盐)
t = new Test();
这将在堆栈上创建一个Test类型的对象(不需要对它进行淡化处理。一旦退出当前上下文,它就会消失)
Test t2;
修改强>
您的示例有效,因为编译器优化了您的代码:它注意到您不使用任何成员,因此它可能无法为您查找实例。
答案 3 :(得分:1)
第一个是创建对象实例的方法。
第二个on不是创建对象实例的方法。它只是声明一个指针,它仍未被初始化。
答案 4 :(得分:1)
更新后:它仍然成功调用bla()的原因只是未定义的行为。因为这正是C ++标准定义当您处理不安全的内存时所发生的事情(在这种情况下,指针指向的某个任意地址) - 行为未定义。
答案 5 :(得分:0)
Test* test;
test->bla();
正如其他答案所述,Test* test
不会创建任何对象。它是指向Test
的未初始化指针。除非将其初始化为指向有效的Test
对象,否则它不会指向任何有效的内容。
取消引用未初始化的指针会产生 Undefined Behaior 。
在您的情况下,它不会崩溃,因为您没有在this
内引用bla()
然而,仍然未定义的行为取消引用单一化test
。
重申上述观点,以下示例将主要崩溃。
#include<iostream>
class Test
{
public:
int i;
void bla(void)
{
std::cout << "test" << std::endl;
std::cout << "test->i" << this->i <<std::endl;
}
};
int main(void)
{
Test* test;
test->bla();
return 0;
}
答案 6 :(得分:0)
正如其他人已经说过的那样,你很幸运,你触发的未定义行为看起来像你想要的那样(主要是因为你的Test :: bla()几乎就像一个全局自由函数)。要查看示例崩溃和刻录,只需添加一些非平凡的类成员:
class Test {
public:
void bla(void) {
std::cout << "test: " << x << std::endl;
};
int x;
};
您可以将原始示例视为自由功能
void bla(Test * p) { std::cout << "test" << std::endl; }
你恰好用垃圾参数调用,但由于你没有使用参数,所以没有任何不好的事情发生。在我修改过的示例中,我们尝试访问p->x
并死亡。