为什么这段代码只打印42?
有人可以向我解释为什么这段代码只打印“42”而不是“created\n42”吗?
#include <iostream>
#include <string>
#include <memory>
using namespace std;
class MyClass
{
public:
MyClass() {cout<<"created"<<endl;};
int solution() {return 42;}
virtual ~MyClass() {};
};
int main(int argc, char *argv[])
{
auto_ptr<MyClass> ptr;
cout<<ptr->solution()<<endl;
return 0;
}
顺便说一句,我在解决方案中尝试了使用不同值的代码,并且总是得到“正确”的值,所以它似乎不是随机的幸运值。
Could somebody please explain to me why does this code only print "42" instead of "created\n42"?
#include <iostream>
#include <string>
#include <memory>
using namespace std;
class MyClass
{
public:
MyClass() {cout<<"created"<<endl;};
int solution() {return 42;}
virtual ~MyClass() {};
};
int main(int argc, char *argv[])
{
auto_ptr<MyClass> ptr;
cout<<ptr->solution()<<endl;
return 0;
}
BTW I tried this code with different values in solution and I always get the "right" value, so it doesn't seem to be a random lucky value.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
因为它表现出未定义的行为 - 您取消引用空指针。
当你说:
你创建了一个不指向任何东西的自动指针。 这相当于说:
然后当你说:
你取消引用这个空指针。 这样做在 C++ 中是未定义的 - 对于您的实现来说,它似乎有效。
Because it exhibits undefined behaviour - you dereference a null pointer.
When you say:
you create an autopointer which doesn't point to anything. This is equivalent to saying:
Then when you say:
you dereference this null pointer. Doing that is undefined in C++ - for your implementation, it appears to work.
std::auto_ptr 不会自动为您创建对象。 也就是说,main 中的
ptr
被初始化为 null。 取消引用这是未定义的行为,您只是碰巧很幸运,结果得到了 42。如果您实际创建了对象:
您将得到您期望的输出。
std::auto_ptr will not automatically create an object for you. That is,
ptr
in main as it stands is initialized to null. Dereferencing this is undefined behavior, and you just happen to be getting lucky and getting 42 as a result.If you actually create the the object:
You will get the output you expect.
首先,请记住
auto_ptr
的->
运算符本质上是转发到所包含的指针。 因此,对于此讨论,main
中的代码等效于:然后请注意,编译器倾向于以非常类似于带有
this< 的非成员函数的方式实现成员函数。 /code> 指针作为另一个函数参数传递。 因此,从当前编译器的角度来看,
main
中的代码的行为就像:解决方案写为:
在这种情况下,很明显为什么没有崩溃。
然而,正如其他人已经提到的,这些是编译器如何实现 C++ 的内部细节,语言标准并未指定。 因此,从理论上讲,这段代码可以在一个编译器上按照此处描述的方式工作,但在另一个编译器上完全崩溃或执行其他操作。
但实际上,即使标准不保证这种行为,任何特定的编译器都可以保证它(如果他们愿意)。 例如:由于 MFC 依赖于此行为,因此 Visual Studio 不太可能停止支持它。 当然,您必须研究可能使用您的代码的每个特定编译器,以确保它们确实保证此行为。
First, keep in mind that the
->
operator ofauto_ptr
is essentially forwarded on to the contained pointer. So for this discussion, your code inmain
becomes equivalent to:Then note that compilers tend to implement member functions in ways that act very much as if they were non-member functions with the
this
pointer passed as another function argument. So from your current compiler's point of view, your code inmain
acts as if it was:with solution written as:
In which case it becomes obvious why there wasn't a crash.
However as others have already mentioned, these are internal details of how compilers implement C++, which are not specified by the language standard. So in theory this code could work as described here on one compiler but crash or do something else entirely on another compiler.
But in practice, even if the standard doesn't guarantee this behavior, any particular compiler could guarantee it if they want to. For instance: since MFC relies on this behavior, it is very unlikely that Visual Studio will ever stop supporting it. Of course, you would have to research each particular compiler where your code might be used to make sure that they actually guarantee this behavior.
因为你不知道问题的答案 xD
看来你没有调用构造函数,对吧?
Because you don't know the question to the answer xD
It seems you're not calling the constructor, right?
您没有创建该对象的实例。
您只是创建一个智能指针。
当您调用该方法时,您将取消对 NULL 指针的引用,因此正如 Neil 提到的,您现在处于未定义的行为中。 但由于您的代码不会尝试访问任何成员变量,所以幸运的是它不会崩溃。
尝试这个:
You a re not creating an instance of the object.
You are only creating a smart pointer.
When you call the method you are de-referencing a NULL pointer, so as Neil mentioned you are now in undefined behavior. But since your code does not try and access any member variables it luckily does not crash.
Try this:
因为
ptr
尚未初始化,而且你很幸运。 您应该首先为其调用new
:Because
ptr
is uninitialized and you're lucky. You should first callnew
for it:您不会崩溃,因为“解决方案”方法不需要实际使用类成员。 如果你要返回一个成员或其他东西,你可能会遇到崩溃。
You're not getting a crash because the "solution" method doesn't need to actually use the class members. If you were returning a member or something, you'd probably get a crash.