如果你想,你可以在这里阅读更多未定义的行为。
如果违反了语言的某些规则,则未定义的行为将使整个程序变得毫无意义。编译器基本上可以决定要做什么。
但是就像在cppreference中提到的:
编译器不需要诊断未定义的行为(尽管许多简单的情况被诊断出来),并且编译后的程序不需要做任何有意义的事情。所以简而言之,对程序的行为没有限制。
你的案子h1> 个例子都调用了未定义的行为:
在我的理解中,这可能是错误的,声明指向局部对象的指针是危险的,或者可能没有目的。
下面的全局定义函数Factory
返回一个指向局部对象的指针,它没有任何用途。在调用Factory()
之后,返回的地址指向一个已经被销毁的本地对象。
Foo* Factory()
{
// It is wrong to return the address of a local object!
// It is only for illustration!
Foo local{ 100 };
return &local;
}
调用Print()
会产生一个垃圾值。这到目前为止还可以理解。
现在考虑第二种使用局部作用域的情况,如下所示。
int main()
{
Foo* p ;
{
Foo local{ 100 };
p = &local;
}
p->Print();// 100 is printed even though p is pointing to a local scoped object that has been destroyed.
return 0;
}
我不明白的是为什么我仍然可以在应该被销毁的指向对象上调用Print()
。欢迎任何评论!
#include <iostream>
class Foo
{
private:
int _data;
public:
Foo(int data) :_data{ data }
{
std::cout << "Ctor: " << this << std::endl;
}
~Foo()
{
std::cout << "Dtor: " << this << std::endl;
}
void Print()
{
std::cout << "Data: " << _data << std::endl;
}
};
Foo* Factory()
{
// It is wrong to return the address of a local object!
// It is only for illustration!
Foo local{ 100 };
return &local;
}
int main_1()
{
Foo* p = Factory();
p->Print();// Garbage gets printed because p is pointing to a local object that has been destroyed.
return 0;
}
int main_2()
{
Foo* p ;
{
Foo local{ 100 };
p = &local;
}
p->Print();// 100 is printed even though p is pointing to a local scoped object that has been destroyed.
return 0;
}
标题>未定义行为
首先,我想简单解释一下未定义行为。如果你想,你可以在这里阅读更多未定义的行为。
如果违反了语言的某些规则,则未定义的行为将使整个程序变得毫无意义。编译器基本上可以决定要做什么。
但是就像在cppreference中提到的:
编译器不需要诊断未定义的行为(尽管许多简单的情况被诊断出来),并且编译后的程序不需要做任何有意义的事情。所以简而言之,对程序的行为没有限制。
你的案子h1> 个例子都调用了未定义的行为:
int main_2()
{
Foo* p ;
{
Foo local{ 100 };
p = &local;
}
p->Print();
return 0;
}
int main_1()
{
Foo* p = Factory();
p->Print();
return 0;
}
int main_2()
{
Foo* p ;
{
Foo local{ 100 };
p = &local;
}
p->Print();
return 0;
}
int main_1()
{
Foo* p = Factory();
p->Print();
return 0;
}
就像我们学过的,未定义行为是未定义的。所以任何事情都有可能发生。在第二种情况下,您的编译器可能足够聪明地注意到这个问题。