为什么是不可能有一个参考空虚?我唯一找到的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。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top