为什么是不可能有一个参考,到空虚?
-
19-08-2019 - |
题
为什么是不可能有一个参考空虚?我唯一找到的C++的标准是这条线, 8.3.2.1
一个声明,指定类型的"参考 简历 void"被虐待的形成。
为什么是这样的吗?为什么我不能写一种"通用"的功能接受 void&
?
只是要清楚,我没有有用的应用中心在使用一个参考对无效可能比使用的模板,但我只是好奇的理由禁止这一建造。
要澄清一点,我的理解是,使用一个参考对无效"是"将是毫无意义作为解除引用的指针对无效。然而,我可以转换为一个参考-对sometype 为了要使用它,不是吗?事实上,我看不出为什么以下段可以...
void foo(void *data)
{
int *i = reinterpret_cast<int*>(data);
// do something with i
}
...而这一无法:
void foo(void &data)
{
int &i = reinterpret_cast<int&>(data);
// do something with i
}
解决方案
如果你确实有一个参考作废,你会怎么做呢?它不会是一个数字或字符,或一个指针,或类似的东西。假想的通用函数不能在其上执行任何操作,除了利用其地址(而不是其尺寸)。
“无效”有两种用途:可以放弃类型的任何知识(如无效*),并指定什么,而不是什么(void函数返回)。在两种情况下是有可能说一下,除了它可具有一个地址的空隙的东西任何东西。
如果你不能想办法东西是有用的,我做不到,那至少证明的东西是没用的,而且很可能是这里的理由至少一部分。
其他提示
问问你自己第一次,你会如何去引用一个空指针?
void *p = /*something*/ ;
cout << *p << endl;
在上面的代码是没有意义的,原因之一,我们有空隙,所以我们可以说:“我要在这里做一些通用指针工作,我不知道,也不关心什么,我指着”。 根据定义,编译器不知道什么是无效*点,因此它不能取消对它的引用。你可以 - 通过铸造 - 但是编译器不能
要的空隙的引用sufferes从相同的问题,通过定义中的数据指出,没有一个类型,因此它不能在任何有意义的方式被引用。
要引用它你 - 程序员 - 需要将它转换为另一种类型的,则可以有一个类型引用它
。不知道如果我解释这个问题,以及我想。
的Ruben,任何想法?
编辑:要回答你的修改
在第一个函数,其中传递无效*数据。 数据是一个完全有效的项目,你可以用它计算,或者如果你已经实现了一些记录,就可以登录了。
logger << data;
,你会得到的地址数据点。如果您尝试取消引用数据,编译器会给你一个错误(没有C ++编译器方便的时刻,所以不知道实际的错误)。 例如
void* data = /* some assignment */;
logger << *data; // compiler error.
现在,编译器不会让你解引用一个void *因任何原因(它没有意义),同样代表参考作废和数据,只是因为它是一个参考的它含蓄地提领所有的时间。编译器不会让你提领上一个操作一个void *,它不会让你解引用它不断。
void& data = /* some assignment *.;
logger << data; // means same as logger << *data above
您不能做的 ANYTHING 以数据的除非把它的地址,并有一个非常好的 - 安全 - 内置到languge方法来做到这一点,即
void* data;
时此进行任何更多的意义?
一个引用是对某事实例的引用。
某个实例的类型不能为void
的。
的东西任何实例必须具有特定的类型(以及可能的基类型)。
这里有一个摘要不同的东西,已经说了,我想到的。
主要有两个原因为什么参考到的空隙是不允许的
1 他们会被完全无用的。
事实上,如果我们回头看看这次的C、无效的指针有两个目的:
- 存管理(例如malloc)
- 泛型(编写职能可以接受任何类型的参数)
当C++出来,模板成为最好的解决方案来实施泛型.然而,定义存管理仍然不得不可能,之间的互操作性C++和C是一个主要问题,因此void*是犹存.一个假设的空隙参考将是有帮助与存储管理,并且泛型是已经复盖的,因此基本上,它会几乎没有使用(除了为保证非nullness如下所述)。
2 你就不能用它做任何事情
当使用一个无效的指针,你不可以引用;转向的情况下参考文献,这意味着不能使用(总是假设的)无效的参考。所以
void *data = // something
// using *data and data-> is forbidden
void &data = // something
// using data is forbidden
然而,我们可以认为一个使用情况的基准也不会将"引用"(这句话是非常不正确的,但是你让我一点),但在这里我们只能采取其地址。让我们假设我有下列功能:
void foo(void *dataptr)
{
assert(dataptr != NULL); // or != 0
// do something with dataptr
}
为了避免这恼人的断言,我可以写的功能这一方式:
void foo(void &dataref)
{
void *data = &dataref;
// do something with data
}
然而,对于这项工作, &dataref
需要相当于 dataptr
, 它不是这种情况: &dataref
相当于 &*dataptr
!
因此,即使把地址意味着取消引用,至少在概念上(幕后,第一等同的可能是真实的,但在语义的水平是不可)。因此,绝对没有使用我们可以让的数据,所以无效的参引是一个差。
从技术上讲,所有这是保证的是,对一个对象的引用为它的别名。发动机罩的参考参数传递与指针做下是一个实现细节。这可能会造成混淆,因为引用重复使用和操作这也是解决-的,但要记住的是,运营商实际上是在不同的上下文有不同的含义(它表示一个引用类型变量或参数声明,否则它的地址的,除非它是按位与)。因为它在技术上只是一个对象的别名,参考是“总是解除引用”作为杞人忧天说明。
OK,有一件事是窃听我关于这一点。一个void*
的想法,如上面提到的,是你还有包含地址一个合法的变量,但类型被忽略。这似乎是允许的,因为我们仍然可以与地址数据的工作 - 类型是在这方面有点画蛇添足(或不那么重要)。解引用它是坏的,因为尝试的访问成员的无厘头例如p.mem
。我们不知道指什么课,从而跳转到,V表指针跟随记忆。
然而,它会接着似乎使某种意义上说p
自身的将是美好的,因为它会只引用对象,但没有它的数据。无需类信息,这样做,只是地址。据我所知,绝对没有使用了这一点,但它在定义是很重要的,当事情打破。允许这个概念,一个C ++参考(不断解除引用但不访问任何东西)例如void& ref = static_cast< &void >(obj)
也有道理,因此将允许无效引用。我不是说任何人都应该把它上升与主事者,但从一个“决策意识”的观点,它会似乎是正确的,不是吗?
由于吕克Touraille上文所指出的(至少,这是我的解释),它可以实现,但问题是语义之一。在合理的解释我能来是因为对象变量是一个“标签”,为内存的序列,类型是重要的语义值。因此,指针,被思想为与地址值的变量,治疗的类型如有些多余 - 而不是键来定义它
会有人同意吗?
可以认为一个引用作为解除引用指针。在语法上,你把一个参考,就好像它是不是指针:你不需要*运算符取消引用它,你可以使用。而不是 - >来访问它的成员
然而,可以不取消引用void
指针。正如二进制杞人忧天指出尝试这样做,会给你一个编译器错误。如果你不能有一个解除引用的空隙的指针,这意味着你不能有一个空隙参考。
如果他们是,他们会从语义上指针未分化的,并且将达到语法糖。参考说,“我指的东西,就是这种类型的。”允许无效或空引用会削弱由指针这种差异。
当然,它仍然是可能的参考来引用的对象不存在了,但是这是个例外。
以下是不的空隙引用的概念的防御。我给它从野生的轶事。问问自己,如果它不闻滑稽。
我公司是第一个使用C ++商购的,并且最初使用 Cfront的编译之一。早期的开发者仍然在学习的语言,一般采用在书中每招(运营商无处不在!)。这里是他们认为一招是凉爽:
void Foo::something(int action, ostream &os = *(ostream *)0)
{
ostream *os_p = &os;
if (&os == (ostream *)0) {
os_p = &cerr;
}
// continue with method
}
所以,在这里你有,不是一个空洞的参考,而是有潜在的无效的绑定类型引用!片刻的思考或许应该提出更好的替代品,以这种特殊的成语......
<强>空隙强>是什么,根据定义,不存在,所以它是不符合逻辑的有它的ADRESS。