以下代码检查空引用,并在检测到时使用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
,但无效但遇到同样的情况;该程序终止于同一行。
任何人都可以解释一下,为什么即使在对象创建成功之后程序也无法在此特定行执行,并且在语法或逻辑不正确的情况下,建议我使用正确的一个?评论中提到了该计划的预期途径。
答案 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;
}