Why does this code only print 42?

做~自己de王妃 提交于 2019-12-05 07:25:41

Because it exhibits undefined behaviour - you dereference a null pointer.

When you say:

 auto_ptr<MyClass> ptr;

you create an autopointer which doesn't point to anything. This is equivalent to saying:

MyClass * ptr = NULL;

Then when you say:

cout<<ptr->solution()<<endl;

you dereference this null pointer. Doing that is undefined in C++ - for your implementation, it appears to work.

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:

int main(int argc, char *argv[])
{
    auto_ptr<MyClass> ptr(new MyClass);

    cout << ptr->solution() << endl;

    return 0;
}

You will get the output you expect.

First, keep in mind that the -> operator of auto_ptr is essentially forwarded on to the contained pointer. So for this discussion, your code in main becomes equivalent to:

MyClass* ptr = NULL;
cout << ptr->solution() << endl;

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 in main acts as if it was:

MyClass* ptr = NULL;
cout << solution(ptr) << endl;

with solution written as:

int solution(MyClass* this) { return 42; }

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.

Because you don't know the question to the answer xD

It seems you're not calling the constructor, right?

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:

auto_ptr<MyClass> ptr(new MyClass);

Because ptr is uninitialized and you're lucky. You should first call new for it:

auto_ptr<MyClass> ptr( new MyClass );

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!