除了内存分配相关的东西之外,void* 是否必要 [英] Is void* necessary apart from memory allocation related stuff

查看:22
本文介绍了除了内存分配相关的东西之外,void* 是否必要的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

void* 除了 C++ 中与内存分配相关的内容外,是否还需要?可以举个例子吗?

Is void* necessary apart from memory allocation related stuff in C++? Can you give me an example?

推荐答案

记录内存地址

如果你想使用 iostreams 输出一个指针(例如用于日志记录),那么通过 void* 是确保 operator<<< 没有被以某种疯狂的方式超载.

Logging memory addresses

If you want to output a pointer using iostreams (e.g. for logging) then going via void* is the only way of ensuring operator<< hasn't been overloaded in some crazy way.

#include <iostream>

struct foo {
};

std::ostream& operator<<(std::ostream& out, foo*) {
  return out<<"it's a trap!";
}

int main() {
  foo bar;
  foo *ptr = &bar;

  std::cout << ptr << std::endl;
  std::cout << static_cast<void*>(ptr) << std::endl;
}

<小时>

测试 iostream 状态

iostreams 重载 operator void* 作为状态检查,这样像 if (stream)while (stream) 这样的语法是一个简写测试流状态的方法.


Testing iostream status

iostreams overload operator void* as a status check so that syntax like if (stream) or while (stream) is a short hand way of testing the stream status.

有时您可能希望将 void* 与模板元编程一起使用,作为减少的全部内容,例如使用 SFINAE 技巧,但通常有一种更好的方法可以使用一种或另一种形式的部分特化.

You might want to use void* with template metaprogramming sometimes as a reduced catch all, e.g. with SFINAE tricks, but more often than not there's a nicer way around it using a partial specialisation of one form or another.

正如 Alf 在评论中指出的那样,dynamic_cast 对于获取层次结构中最派生的类型也很有用,例如:

As Alf pointed out in the comments dynamic_cast<void*> is also useful for getting at the most derived type in a heirarchy, e.g.:

#include <iostream>

struct other {
  virtual void func() = 0;
  int c;
};

struct foo {
  virtual void func() { std::cout << "foo" << std::endl; }
  int a;
};

struct bar : foo, other {
  virtual void func() { std::cout << "bar" << std::endl; }
  int b;
};

namespace {
  void f(foo *ptr) {
    ptr->func();
    std::cout << ptr << std::endl;
    std::cout << dynamic_cast<void*>(ptr) << std::endl;
  }

  void g(other *ptr) {
    ptr->func();
    std::cout << ptr << std::endl;
    std::cout << dynamic_cast<void*>(ptr) << std::endl;
  }
}

int main() {
  foo a;
  bar b;
  f(&a);
  f(&b);
  g(&b);
}

给出:

foo
0xbfb815f8
0xbfb815f8
bar
0xbfb815e4
0xbfb815e4
bar
0xbfb815ec
0xbfb815e4

在我的系统上.

§ 15.3.1 规定:

§ 15.3.1 states:

异常声明不应表示指向的指针或引用不完整的类型,除了 void*、const void*、volatile void* 或const volatile void*.

The exception-declaration shall not denote a pointer or reference to an incomplete type, other than void*, const void*, volatile void*, or const volatile void*.

因此,捕获指向不完整类型的指针的唯一合法方法似乎是通过 void*.(虽然我认为如果你真的需要使用它可能会有更大的问题)

So it seems to be the only legal way of catching a pointer to an incomplete type is via void*. (Although I think there's possibly bigger issues if you actually needed to use that)

void* 有很多传统"C 用于存储指向数据的指针而不知道它是什么,但在新的 C++ 代码中几乎总是有更好的表达方式功能.

There are a lot of "legacy" C uses for void* for storing pointers to data without knowing what it is, but in new C++ code there is almost always a better way of expressing the same functionality.

这篇关于除了内存分配相关的东西之外,void* 是否必要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆