void指针vs函数参数中的对象

时间:2014-12-09 14:54:03

标签: c# c++

如果你现在不正确地在编译时将该类型定义为什么,那么在C ++中传递void指针的模仿程度如何模仿object

3 个答案:

答案 0 :(得分:2)

让我们在其他答案中得到一些错过的东西。 C#中的所有对象(结构除外)都作为指针传递。 C#(和Java)隐藏了指针语法,因为它可能出错的所有可怕的事情,因为即使是经验最丰富的C / C ++程序员也会无意中通过指针滥用来霰弹,这是一件非常好的事情。

C中的

void *(在C#中 - 如果打开不安全的代码则存在)是一个指向地址的指针,绝对没有暗示可能是什么。在C早期,既没有void也没有void *。如果我们想要一个函数不返回任何内容,我们就没有输入return语句。它仍然隐含int,但价值是不可预测的。如果没有void *,我们通常使用char *,但程序员并不喜欢这样,因为它暗示了指向字符或字符串的指针以及如何在指针上执行数学操作的含义{ {1}}。使用sizeof(char) != 1并不意味着您指向任何特定类型,并且程序员最了解void *指向的内容(扰流板:大多数程序员不要)

那你为什么要用这个呢?一种典型的用途是在API中将指针用作不透明类型。例如:

void *

这一切都很好 - 这个API的消费者并不知道该设备是什么。很遗憾,由于任何内容都是extern void *get_device(); extern int is_device_active(void *device); ,因此该API可让您执行一些非常糟糕的事情:

void *

然而,你的编译器会在没有窥视的情况下允许这样做,这实际上使char *str = get_device(); /* wrong */ size_t len = strlen(str); /* doubly wrong */ int active = is_device_active("hi mom!"); /* can't express how wrong */ 在这种情况下不那么有用。

在C#中,void *完全是另一个野兽。它对指针的含义有很强的影响。它可以是object,也可以是允许您这样做的类的实例:

  • 等于
  • 的Finalize
  • 的GetHashCode
  • 的GetType
  • MemberwiseClone
  • 的ToString

无论实际物体是什么,所有这些都保证在那里。使用null,除了API文档中的承诺之外,您什么都没有。

C中void *的最佳用途是void *(及其变体)和malloc(),因为它们不会指示它们指向的类型。

另外,如果您想知道如何在C中实际呈现不透明的API,那么典型的模式是:

free()

答案 1 :(得分:1)

指针指的是变量

object的实例引用

这是一个非常关键的区别。使用指针可以改变另一个变量(通常是当前不在范围内的变量)。使用object实例,您只能改变,可能是另一个变量也引用的值,但这仍然是一个关键区别。

因为指针指向变量,所以通过指针可以观察到引用变量变量的突变。指针也能够改变该变量。另一方面,object实例与另一个变量无关。即使它引用的对象是由另一个变量引用的,其他变量的变化也不会通过object实例观察到,并且它也无法改变其他变量。

还有一个事实是,object引用一个值类型,需要将值类型装箱。这可能会影响性能,因为值最终会被复制,但也会产生显着的语义差异。 object引用不会显示源变量的变异,而使用void指针则会显示它们。

答案 2 :(得分:0)

我可能没有最终的答案,但我知道一些不同的事情:

  • 无效指针可以指向任何东西。从字面上看!这意味着你在使用void指针时必须知道你指向的是什么,否则你可能会在程序中弄乱很多。这意味着您需要通过编译时间知道类型以正确使用它。这就是为什么处理void指针的函数要求它的类型大小(使用sizeof)以及类似的东西以及指针。

  • 对象是您在C#中创建的任何类的基础。但与C / C ++不同,您可以使用反射了解其类型。这意味着无论您以前是否知道此类型,都可以处理。此外,对象是C#对象......这意味着你根本没有引用任何东西......你正在引用C#实例,不管它是什么类型。