【发布时间】:2015-03-31 05:48:21
【问题描述】:
我正在编写一些使用 fstream read() 函数的代码,该函数需要一个 char* 作为缓冲区。稍后,我想将此缓冲区中的字节用作无符号字符,所以我要么必须:1. 将缓冲区声明为 char*,然后稍后为每个元素执行 static_casts,2. 声明缓冲区作为 unsigned char* ,然后在我将其传递给 read 函数时执行 reinterpret_cast,或者 3. 将缓冲区声明为 char* 并创建一个转换指针,用于将缓冲区作为 unsigned char 访问。
这是一个sn-p:
char* buf = new char[512];
unsigned char* ubuf = reinterpret_cast<unsigned char*>(buf);
fstream myfile;
myfile.open("foo.img");
myfile.seekg(446);
myfile.read(buf, 16);
//myfile.read(reinterpret_cast<char*>(buf), 16);
int bytes_per_sector = ubuf[1] << 8 | ubuf[0];
...
我喜欢这种方式,因为我只需要转换一次,我可以访问缓冲区作为任一类型,而无需每次都进行转换。但是,这是一个好习惯吗?这里有什么可能出错的地方吗?使用 reinterpret_cast 让我有点紧张,因为我通常不使用它,而且我被告知要小心使用它很多次。
【问题讨论】:
-
这是
reinterpret_cast实际上安全且有意义的极少数情况之一。 -
@Deduplicator 呃。请不要推荐使用 C-style casts。请考虑在 C++ 中已弃用的那些。 在这种情况下是安全的,但是直接禁止它们并避免潜在的混淆是一个更简单的规则。而
reinterpret_cast,更明确,也使代码更具可读性,因为它清楚地告诉读者正在执行哪个演员。 -
@Deduplicator C++ 强制转换 replace C 强制转换。使用 C 强制转换既无用也不合理,因为总是有更具体的 C++ 强制转换。没有理由使用 C 强制转换。您的“可能不够笨重”是没有意义的,因为 1. C 演员表只会做适当的 C++ 演员表所做的事情,而 2. 在这种情况下,这没什么。
-
@Deduplicator philipxy 和我的观点是
reinterpret_cast是明确的,因此即使不是类型安全也可以提高可读性。reinterpret_cast具有明确定义的含义。相比之下,C 风格的演员表则不然。它可以表示许多事物中的任何一种,因此在代码中使用它会掩盖读者的实际语义。这通常被认为是一个非常糟糕的主意。 -
... 现在,如果我必须重新设计 C++,我希望将 c-style-cast 降级为隐式,函数式降级为隐式+任何 ctor+conversion-operator(这是羞耻
implicit_cast不在 C++14 中),并使其他 4 种(静态、常量、动态、重新解释)简短而简洁的变体。
标签: c++ pointers fstream reinterpret-cast