Auto和Void之间的区别?

时间:2016-04-27 15:59:28

标签: c++ pointers c++11 void-pointers

我正在阅读C ++入门书(第五版),我对正在阅读的书有疑问。它说:

  

类型final是一种特殊的指针类型,可以保存地址   任何对象。像任何其他指针一样,final指针保存一个地址,   但该地址的对象类型未知。

好的,所以我明白了,但......我的声明有很多矛盾。首先,你不能使用void*吗?它不像void*那样做吗?含义不是

auto

void

同样的?

其次,它说附加地址的类型是未知的。你不能用void *somePtr; 来获取类型吗?像这样:

auto *somePtr;

5 个答案:

答案 0 :(得分:11)

您是否尝试通过编译器运行示例?碰巧,没有

auto * p;  // error

,也不

int a = 0;
void * p = &a;
std::cout << typeid(*p) << '\n';  // error

将同时编译

void * p;

int a = 0;
auto * p = &a;
std::cout << typeid(*p) << '\n';

很好。

void *auto *提供一个非正式且易于记忆的类比,请将void * p视为告诉编译器

  

不关心p指针指向的内容,我会自己处理它(在运行时)。

auto * p = (expression)告诉编译器

  

请为我(在编译时)确定({指针]类型(expression)评估的内容,并相应地设置p的类型。

事实上,auto *很少有用。您可以简单地编写auto,如果初始化表达式是指针类型,auto也将被推断为指针。

答案 1 :(得分:9)

auto使用编译时type inference:变量有一个确定的类型,它是正确的类型,但是从它的值推断出类型。在auto变量的整个生命周期中,编译器将确保根据其实际推断类型使用它

void*确实可以保存任何对象的地址,但与auto相反,您必须在使用它之前将void*指针显式转换为其他类型。与auto不同,转换是显式的,与auto不同,编译器无法警告不正确的使用。

答案 2 :(得分:2)

从编译器的角度来看

  • 在C ++ 11中auto使用与template argument deduction相同的推理规则。它基本上告诉编译器:“从初始化器中删除类型。”
  • void *告诉编译器:“这是一个指向一个对象的指针,该对象的类型在编译时是不可能知道的。”

对于auto,实际类型是在编译时推导,因此编译器可以警告可能的误用。

对于void *,程序员使用reinterpret_cast在代码中推导出实际类型,以强制转换为已知指针类型,通常是在该段的执行点代码。

从程序员的角度来看

  • 嘿编译器我太懒或太笨拙而无法编写类型。我只是auto它让你弄明白其余的。 (它看起来比我要写的类型要小。除了 int 。)
  • 嘿编译器,你不敢惹我的void *。当我需要时,我会在运行时中找出类型(在代码中...)。
    • 对运行时多态性很有用,因为相同的指针可用于指向上下文中所需的不同类型的对象。
    • 如果您正在编写基类,并且客户端需要存储客户端定义的用户定义类型的对象,这也很有用。

所以 auto NOT 等同于voidvoid表示 nothing 。实际上,您甚至无法声明void类型的变量。 void *但是特殊类型的指针可以指向任何内容!并且auto *是多余的,只需使用普通的auto代替。

在您的示例中,

int a = 5;
auto *somePtr = 5;
std::cout << typeid(*somePtr).name(); << std::endl;

您已将地址5分配给somePtr,这是非法的。毫无疑问地说*somePtr在这种情况下也是非法的。虽然auto可能推导为int,但这是您要打印的内容。

使用现代C ++技术,除了深入任何库实现内部之外,您很少看到void *reinterpret_cast或任何原始指针。

答案 3 :(得分:1)

回答你的第一个问题,

void和auto不一样。 sizeof(allDivisions[0].quarterlySales[0])

代表:

自动a = 5 //&#39; a&#39;是整数

自动a = 5.0 //&#39; a&#39;是float等类型,

解除引用时可以观察到实际差异。

以上陈述&#34;在解除引用时可以观察到实际差异&#34;回答你的第二个问题。

void *不能被引用,而auto *可以是deferenced

答案 4 :(得分:0)

如果是自动变量,它将采用变量的数据类型。例如 Auto obj = class_obj。这里class_obj的数据类型变为obj的数据类型。你不需要明确记住并输入强制转换。如果是void *,你需要知道数据类型并明确地输入类型。