Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c++;:为什么可以';t';这';是一个空PTR吗? 在我早期使用C++时,我记得你可以用空指针调用一个成员函数,并在成员函数中检查: class Thing {public: void x();} void Thing::x() { if (this == NULL) return; //nothing to do ...do stuff... } Thing* p = NULL; //nullptr these days, of course p->x(); //no crash class Foo { static auto bar_st(Foo* foo) { if (foo) return foo->bar(); } }_C++_This_Nullptr - Fatal编程技术网

c++;:为什么可以';t';这';是一个空PTR吗? 在我早期使用C++时,我记得你可以用空指针调用一个成员函数,并在成员函数中检查: class Thing {public: void x();} void Thing::x() { if (this == NULL) return; //nothing to do ...do stuff... } Thing* p = NULL; //nullptr these days, of course p->x(); //no crash class Foo { static auto bar_st(Foo* foo) { if (foo) return foo->bar(); } }

c++;:为什么可以';t';这';是一个空PTR吗? 在我早期使用C++时,我记得你可以用空指针调用一个成员函数,并在成员函数中检查: class Thing {public: void x();} void Thing::x() { if (this == NULL) return; //nothing to do ...do stuff... } Thing* p = NULL; //nullptr these days, of course p->x(); //no crash class Foo { static auto bar_st(Foo* foo) { if (foo) return foo->bar(); } },c++,this,nullptr,C++,This,Nullptr,这样做可能看起来很愚蠢,但在编写递归函数来遍历数据结构时,这绝对是一件美妙的事情,在这种情况下,导航可能很容易陷入空值的死胡同;导航函数可以在顶部对NULL进行一次检查,然后轻松地调用自己来尝试更深入地导航,而不必在代码中添加额外的检查 至少根据g++的说法,自由(如果曾经存在的话)已经被撤销了。编译器对此发出警告,如果编译优化,则会导致崩溃 问题1:C++标准(任何味道)不允许这个空吗?还是g++只是在我面前 问题2。更具哲理的是,为什么?”这只是另一个指针。指针的荣耀在于它们可以是null

这样做可能看起来很愚蠢,但在编写递归函数来遍历数据结构时,这绝对是一件美妙的事情,在这种情况下,导航可能很容易陷入空值的死胡同;导航函数可以在顶部对NULL进行一次检查,然后轻松地调用自己来尝试更深入地导航,而不必在代码中添加额外的检查

至少根据g++的说法,自由(如果曾经存在的话)已经被撤销了。编译器对此发出警告,如果编译优化,则会导致崩溃

问题1:C++标准(任何味道)不允许这个空吗?还是g++只是在我面前


问题2。更具哲理的是,为什么?”这只是另一个指针。指针的荣耀在于它们可以是null ptr,这是一个有用的条件

我知道我可以通过生成静态函数来解决这个问题,将指针作为第一个参数传递给数据结构(Helllo Days of C),然后检查指针。我只是很惊讶我需要这么做

编辑:要投票表决一个答案,我想看看《标准》中关于为什么不允许这样做的章节。请注意,我的示例在任何时候都不会取消引用NULL。这里没有任何东西是虚拟的,p被复制到“参数this”中,但在使用前进行检查。没有顺从发生!因此,NULL的解引用不能用作UB的声明

人们会下意识地对*p做出反应,并假设如果p为空,那么它是无效的。但事实确实如此,证据如下: 事实上,当指针p作为*p出人意料地有效时,它会调用两种情况:当p为null时,或者当p将一个元素指向数组的末尾时。你永远不能使用*p的值。。。除了带上它的地址&*其中p==nullptr对于任何指针类型p都是有效的。可以指出,p->x()实际上是(*p).x(),但在一天结束时,它转换为x(&*p),这是非常好的格式和有效的。对于p=nullptr。。。它只是变成了x(nullptr)


我认为我应该与标准界进行辩论;在匆忙削弱无效引用概念的过程中,他们留下了不清晰的措辞。因为这里没有人要求p->x()是UB而不要求它是UB,因为*p是UB;因为*p肯定不是UB,因为x()的任何方面都没有使用引用值,所以我将把这归结为g++对标准歧义的过度反应。使用静态函数和额外参数的完全相同的机制定义得很好,所以它不会停止我的重构工作。考虑撤回的问题;可移植代码不能假定此==nullptr将起作用,但有一个可移植的解决方案可用,因此最终这并不重要。

如果
nullptr
,则意味着您调用非静态成员函数时未使用有效实例,例如指针设置为
nullptr
。因为这是禁止的,所以要获取null
this
必须已经处于未定义的行为中。换句话说,
这个
永远不会是
nullptr
,除非您有未定义的行为。由于未定义行为的性质,您可以将语句简化为“
绝不是
nullptr
”,因为在存在未定义行为的情况下不需要维护任何规则。

C++不允许调用null对象的成员函数。对象需要标识,并且不能存储到空指针。若成员函数读取或写入由空指针引用的对象的字段,会发生什么情况

听起来您可以在代码中使用它来创建想要的结果

空指针在面向对象语言中被认为是有问题的实体,因为在大多数语言中它不是对象。这就需要专门处理空值情况的代码。而检查特殊的空指针是标准。还有其他方法。Smalltalk实际上有一个NullObject,它有自己的方法。与所有对象一样,它也可以扩展。Go编程语言确实允许为nil(听起来像问题中需要的东西)调用结构成员函数

问题1:C++标准(任何味道)不允许这个空吗? 还是g++只是在我面前

<> C++标准不允许它是官方的“未定义行为”,你必须避免这样做,否则你会得到一点。特别是,优化器在进行优化时会假定this指针为非NULL,从而导致运行时出现奇怪/意外的行为(我从经验中了解到:)


问题2。更具哲理的是,为什么?”这只是另一个指针。 指针的荣耀在于它们可以是null ptr,这是一个有用的方法 条件


我不确定这是否重要,真的;这是C++标准中指定的,它们可能有其原因(哲学上的或其他的),但是由于标准指定了它,编译器希望它,因此作为程序员我们必须遵守它,或者面对未定义的行为。(你可以想象另一个世界,允许使用空指针,但我们不住在那里)

问题已经得到了回答-取消对空指针的引用是未定义的行为,使用
*obj
obj->
都是取消引用

现在(因为我假设您对如何解决这个问题有疑问),解决方案是使用静态函数:

class Thing {public: void x();}

void Thing::x()
{ if (this == NULL) return; //nothing to do
   ...do stuff...
}

Thing* p = NULL; //nullptr these days, of course
p->x(); //no crash
class Foo {
    static auto bar_st(Foo* foo) { if (foo) return foo->bar(); }
}

话虽如此,我确实认为gcc取消nullptr所有分支的决定是不明智的。没有人从中获益,许多人因此而受苦。有什么好处?

如果您
删除此
(这是可能的,但不推荐)