以下代码检查空引用并在检测到时使用 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/