c++ - 将 NULL 指针强制转换为对象并调用其成员函数之一是否有实际好处?

标签 c++ null offset member-functions

好的,所以我知道从技术上讲这是未定义的行为,但尽管如此,我在生产代码中不止一次看到过这种情况。如果我错了,请纠正我,但我也听说有些人使用这个“功能”作为当前 C++ 标准缺失方面的合法替代品,即无法获取地址(好吧,真正偏移)的成员函数。例如,这是 PCRE(Perl 兼容正则表达式)库的流行实现:

#ifndef offsetof
#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
#endif

有人可以争论在这种情况下利用这种语言的微妙之处是否有效,甚至是否有必要,但我也看到它是这样使用的:

struct Result
{
   void stat()
   {
      if(this)
         // do something...
      else
         // do something else...
   }
};

// ...somewhere else in the code...

((Result*)0)->stat();

这很好用!它通过测试 this 的存在来避免空指针取消引用,并且它不会尝试访问 else block 中的类成员。只要这些守卫到位,它就是合法的代码,对吧?所以问题仍然存在:是否存在实际用例,可以从中受益于使用这种构造?我特别关心第二种情况,因为第一种情况更像是一种语言限制的解决方法。或者是?

附言。对 C 风格的转换感到抱歉,不幸的是,如果可以的话,人们仍然更喜欢少打字。

最佳答案

第一种情况是不调用任何东西。它正在使用地址。这是一个定义的、允许的操作。它产生从对象开始到指定字段的偏移量(以字节为单位)。这是一种非常非常普遍的做法,因为通常需要这样的偏移量。毕竟,并非所有对象都可以在堆栈上创建。

第二种情况相当愚蠢。明智的做法是将该方法声明为静态的。

关于c++ - 将 NULL 指针强制转换为对象并调用其成员函数之一是否有实际好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2569602/

相关文章:

c++ - 使用指向派生类的指针作为模板参数时出错

c++ - "Multiple Definition Of"错误。我究竟做错了什么?

c - 如何删除 C 中的 NULL 输入?

c - 如何计算 C 中连续的空 (\0) 字节?

jquery - 如何使用 jQuery 在垂直滚动站点中获取当前可见幻灯片

jquery - 网站可以滚动,但 Jquery 滚动计算在某些点停止

c++ - 在静态常量成员数组中将 char 类型转换为字符串

c++ - 如何删除在C++中另一个线程中创建的对象

ruby - foo(&nil) 与 foo(&"not a proc") 的行为有何不同?

selenium - 尝试在 Selenium 中拖动/移动元素时如何找出 x 和 y 偏移量?