在c ++中使用空引用检查

时间:2016-06-05 23:42:23

标签: c++ oop pointers reference

以下代码检查空引用,并在检测到时使用letters创建对象。

代码编译并成功创建对象(如预期的那样),但程序意外终止于函数new中的ref.set_dat(55)行(也显示在注释中),这是一种意外行为。< / p>

我似乎不明白为什么在使用main()成功创建对象时,方法调用set_dat()方法会失败?

new

请注意,我已尝试用原始对象class X { private: int *_dat,*__dat; public: X(); // constructor ~X(); // destructor int get_dat() const { return *(this->_dat); } int get__dat() const { return *(this->__dat); } void set_dat(int data) { *(this->_dat)=data; } void set__dat(int data) { *(this->__dat)=data; } }; X::X() { this->_dat=new int(0); // assign default value of 0 this->__dat=new int(0); cout << "Construction Successful\n"; } X::~X() { delete this->_dat; delete this->__dat; _dat=NULL; __dat=NULL; cout << "Destruction Successful\n"; } int main() { X *obj=NULL; X &ref=*obj; if (&ref==NULL) { cout << "NULL REFERENCE DETECTED\n"; obj=new X; } else { // this must not execute cout << "YOU CANT BE HERE!!!\n"; } ref.set_dat(55); // Program terminates at this statement cout << "Data 1 has value " << ref.get_dat() << endl; delete obj; cout << "Delete successful\n"; obj=NULL; if (&ref==NULL) { cout << "NULL REFERENCE\nPROGRAM NOW TERMINATES"; } else { // this block must not execute ref.set_dat(58); ref.set__dat(99); cout << "Data 1 now is " << ref.get_dat() << endl; cout << "Data 2 now is " << ref.get__dat() << endl; delete obj; } return 0; } 替换ref,但无效但遇到同样的情况;该程序终止于同一行。

任何人都可以解释一下,为什么即使在对象创建成功之后程序也无法在此特定行执行,并且在语法或逻辑不正确的情况下,建议我使用正确的一个?评论中提到了该计划的预期途径。

1 个答案:

答案 0 :(得分:7)

X *obj=NULL;
X &ref=*obj;

引用永远不能为NULL,只有指针可以为NULL。但取消引用NULL指针是未定义的行为。这段代码完全没错。

您的代码在中途重新分配obj,因此ref自动更新的唯一方法是ref是指obj变量本身而不是{ X指向的obj对象:

int main() {
    X *obj = NULL;
    X* &ref = obj; // <-- a reference to a pointer
    if (ref == NULL) { // <-- OK
        cout << "NULL REFERENCE DETECTED\n";
        obj = new X; // <-- ref can now access the X
    } else { // this must not execute
        cout << "YOU CANT BE HERE!!!\n";
    }
    ref->set_dat(55); // <-- OK
    cout << "Data 1 has value " << ref->get_dat() << endl;
    delete obj;
    cout << "Delete successful\n";
    obj = NULL; // <-- ref no longer accesses an X
    if (ref == NULL) { // <-- OK
        cout << "NULL REFERENCE\nPROGRAM NOW TERMINATES";   
    } else { // this block must not execute
        ref->set_dat(58); 
        ref->set__dat(99);
        cout << "Data 1 now is " << ref->get_dat() << endl;
        cout << "Data 2 now is " << ref->get__dat() << endl;
        delete obj;
    }
    return 0;
}

或者,将ref更改为指针而不是引用

int main() {
    X *obj = NULL;
    X** ref = &obj; // <-- a pointer to a pointer
    if (*ref == NULL) { // <-- OK
        cout << "NULL REFERENCE DETECTED\n";
        obj = new X; // <-- *ref can now access the X
    } else { // this must not execute
        cout << "YOU CANT BE HERE!!!\n";
    }
    (*ref)->set_dat(55); // <-- OK
    cout << "Data 1 has value " << (*ref)->get_dat() << endl;
    delete obj;
    cout << "Delete successful\n";
    obj = NULL; // <-- *ref no longer accesses an X
    if (*ref == NULL) { // <-- OK
        cout << "NULL REFERENCE\nPROGRAM NOW TERMINATES";   
    } else { // this block must not execute
        (*ref)->set_dat(58); 
        (*ref)->set__dat(99);
        cout << "Data 1 now is " << (*ref)->get_dat() << endl;
        cout << "Data 2 now is " << (*ref)->get__dat() << endl;
        delete obj;
    }
    return 0;
}