为什么这段代码只打印42?

rla*_*azo 6 c++ gcc auto-ptr

有人可以向我解释为什么这段代码只打印"42"而不是"创建\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;
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我在解决方案中使用不同的值尝试了这个代码,我总是得到"正确"的值,因此它似乎不是一个随机的幸运值.

小智 27

因为它表现出未定义的行为 - 您取消引用空指针.

当你说:

 auto_ptr<MyClass> ptr;
Run Code Online (Sandbox Code Playgroud)

你创建一个不指向任何东西的autopointer.这相当于说:

MyClass * ptr = NULL;
Run Code Online (Sandbox Code Playgroud)

然后当你说:

cout<<ptr->solution()<<endl;
Run Code Online (Sandbox Code Playgroud)

你取消引用这个空指针.这样做在C++中是未定义的 - 对于您的实现,它似乎工作.

  • 严肃地说,我希望提问者在接受答案之前稍等一下.我可以建议等待至少12个小时吗? (5认同)
  • 我不会说这很幸运 - 因为`solution()`实际上并没有使用`this`指针(它没有访问任何成员变量或虚函数),所以它不会崩溃也就不足为奇了. (4认同)

GMa*_*ckG 21

std :: auto_ptr不会自动为您创建对象.也就是说,ptr在main中,它被初始化为null.取消引用这是不明确的行为,你恰好幸运,结果是42.

如果您实际创建了该对象:

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

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

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

您将获得您期望的输出.

  • 我一直都知道42是一切的答案,但从未想过空指针也知道这一点.谢谢!BTW为什么这不会引发分段错误? (3认同)
  • 因为这是未定义的行为所做的,它可能看起来有效,或者它可以重新格式化您的计算机.可能它起作用的原因是因为你实际上并没有对班级成员进行操作.编译器看到你正在访问`MyClass :: solution`.它为'this`指针输入0,因为它就是这样,进入函数,得到42作为结果,并返回.给你的clsas一个私有成员`int answer`,在构造函数中将它设置为42,并在`solution()`中返回它,你应该看到崩溃,因为现在你实际上是在尝试使用null`his`指针. (2认同)