c++ - C++中的空引用检查

标签 c++ oop pointers reference

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

代码编译并成功创建对象(正如预期的那样),但程序在函数 main()ref.set_dat(55) 行意外终止(也显示在评论中)这是一种意外行为。

我好像不太明白为什么使用new创建对象成功后调用set_dat()方法会失败?

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;
    }

请注意,我曾尝试用原始对象 obj-> 替换引用 ref,但无济于事;程序在同一行终止。

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

最佳答案

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

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

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

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 更改为 pointer 而不是 reference:

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;
}

关于c++ - C++中的空引用检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37647862/

相关文章:

c++ - 长号。分配

c++ - stringstream str 函数有什么问题?

javascript - 为什么开发人员在 JavaScript 中使用 get 和 set 时使用 "_"?

c - 看似自动释放指针

c# - 在 C# 中有效使用指向任意内存位置的原始指针

c++ - 我在哪里可以找到 'pkunzip.cpp and pkunzip.h"?

c++ - 函数参数 : accepting a null value also

java - getText() 出现为 Null

delphi - 抽象方法的默认实现

c# - 将字符串分配给指向字符的指针