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

zeu*_*eus 1 c++ oop pointers reference

以下代码检查空引用,并使用newif检测创建对象.

代码编译并成功创建对象(如预期的那样),但程序意外终止ref.set_dat(55)于函数行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;
    }
Run Code Online (Sandbox Code Playgroud)

请注意,我已尝试用原始对象替换ref引用obj->,但无效但遇到相同的情况; 该程序终止于同一行.

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

Rem*_*eau 7

X *obj=NULL;
X &ref=*obj;
Run Code Online (Sandbox Code Playgroud)

一个参考不能为NULL,只有指针可以为NULL.但是取消引用NULL指针是未定义的行为.这段代码完全错了.

你的代码obj在中途重新分配,因此唯一ref可以自动更新的方法是if 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;
}
Run Code Online (Sandbox Code Playgroud)

或者,更改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;
}
Run Code Online (Sandbox Code Playgroud)