const void *提供什么价值超过void *?

时间:2012-07-09 15:42:59

标签: c++ const void-pointers reinterpret-cast const-cast

在C ++中,使用const void *作为void *上的函数的参数类型是否有任何价值?由于void *是不透明的,除了用户执行reinterpret_cast之外,是否存在任何修改风险,在这种情况下,他们同样可以在const_cast上执行const void *,因此一个真的买什么?我问,因为我正在使用实用程序模板类来提供共享指针,它在void上提供了专门化以避免void &问题,但没有为const void提供专业化,因此我想知道这是否只是是疏忽还是永远不需要?

6 个答案:

答案 0 :(得分:9)

它提供了const对其他指针类型提供的相同好处:除非明确抛弃const,否则无法修改指向的内容。在接口中,const void*是客户端代码的标志,无论您传入的是什么,都可以读取但不能写入。例如,std::memcpy被声明为

void *memcpy(void *dest, const void *src, std::size_t count);

表示它将读取src并写入dest。当然,如果它真的是用C ++实现的(可能但不太可能),它必须将两个指针都转换为其他类型。

如果您认为这“不会给您带来任何好处”,那么const关键字本身显然没有任何价值。

答案 1 :(得分:4)

memcpy有两个指针参数,一个void*,另一个const void*。第二个参数可以从const char*(或其他指针到const-object-type)参数隐式转换,而第一个参数则不能。

缺少隐式转换是值 - 它会强制用户故意在他们想要的(不太可能的)事件中抛弃const,而不是意外丢弃它。

然后在memcpy或类似函数的实现中,程序员在尝试修改其引用之前必须const_cast或C样式转换const void*参数。他们将能够static_cast非const参数并修改其参考。你需要编写希望的演员表,告诉你一些关于你所做的事情是否明智的事。

我认为如果你的shared_ptr助手函数需要专门处理void,那么他们需要专门处理所有符合cv标准的void。这就是四种情况:voidconst voidvolatile voidconst volatile void。但是,如果这些函数的用户过去曾在shared_ptr<void>上尝试过,并且抱怨它不起作用,但从未在shared_ptr<const void>上尝试过,那么问题可能还没有出现

也许shared_ptr<void>已经不足以让它没有出现。也许那种使用shared_ptr<void>的人往往不介意丢弃cv-qualifiers,因为每当有人最终恢复正确的类型时,他们也会恢复正确的限定符。

来想一想 - shared_ptr<const void>是否正常工作,或调用删除者的shared_ptr中的代码是否需要从T*隐式转换为void* ?我不记得我是否使用过shared_ptr<const T>

答案 2 :(得分:3)

不要忘记const的“文档价值”。即使有人总是可以抛弃它,const也可以表示不应该通过指针改变指向的东西的原始意图。 const_cast(以及此问题reinterpret_cast)应始终谨慎使用,如果需要,应立即让程序员暂停。

答案 3 :(得分:2)

是的,const总是有(某些)相同的优点:文件内容不应该被改变的事实。

想象一下以下代码:

int const object = some_value();
some_function(&object);

如果函数参数声明为void const*,则此调用仅编译,否则客户端需要const_cast来抛弃constness。当然,我们既不希望客户有这种不便,也不希望他们对他们的数据撒谎(通过抛弃常量)。

答案 4 :(得分:1)

“自我记录”代码仍然有好处。

store_pod(const void* data, std::size_t bytes);

没有任何注释可以让您看到指向的数据不会被修改。

另请注意,要打破const承诺,函数需要同时执行const_castreinterpret_cast

答案 5 :(得分:1)

const的所有用途一样,它有两个目的。关于函数的实现,它将帮助编译器检测错误,正如你所提到的,可以通过const_cast(或C风格的强制转换)强制和沉默。

但是const是第二个目的,它提供了不会修改对象的承诺,这样做可以让用户将指针传递给const对象(假设你会信守诺言),有效能够更广泛地使用您的功能。这可以通过这个简单的例子看出:

void foo( const void* );
void bar( void* );
int main() {
    const int value = 10;
    foo( &value );          // correct, the function promises not to modify the value
    //bar( &value );        // error, this would break const correctness
}
相关问题