为什么在读取数据时使用常量指针指向常量值?

时间:2016-03-25 12:01:15

标签: c++ pointers

有没有理由说明为什么要在C ++中使用常量指针来指定常量值?我根本没有得到它背后的原因,因为在src-directory中有人给我他们甚至没有尝试写入var,他们只是从中读取了一个值。

即使你只需要一次阅读,它是否总是使用常量指针到常量变量?

bool
serialize_state(int const fd, game_state const * const state) { ... }

=>在保存的“状态”中常量指向常量game_state,对吧?

3 个答案:

答案 0 :(得分:2)

指向const值的const指针确保客户端既不能更改值也不能更改指针(以便指向不同的指针)。适用时,这种方法有几个优点:

  • 更安全,更少错误/容易出错,因为不可能(或至少很难)改变您不应该的程序部分。
  • 正如Joachim Isaksson在评论中提到的那样,它可以安全地调用具有常量值的某些函数(因为你保证函数不会尝试改变它们)。
  • 当用作函数参数时,可以将临时值传递给它们
  • 它通过代码(而不是通过注释)使意图明确,以便在编译时捕获某些错误

我真的看不到任何真正的缺点,所以我的建议是:当你需要指向同一个const对象的原始指针时,总是使用它们。也就是说,我建议不要使用原始指针,因为std::unique_ptrstd::shared_ptr是标准的一部分。

答案 1 :(得分:1)

在几乎所有情况下,尽可能使变量const是一个好事(tm),因为它表达意图并减少误用的可能性。

然而,当传递参数时,有一个警告。

将指针或引用传递给const资源是明智和正确的:

void foo(const char* text);    
void foo(const std::string& text);

但是当将实际副本作为参数传递时,使其成为const有许多缺点。考虑:

std::string sorted(const std::string source)
{
    // I must copy source again because it's immutable
    auto result = source; // redundant copy
    std::sort(std::begin(result), std::end(result));
    return result;
}

而传递一个可变参数允许函数更有效地使用它:

std::string sorted(std::string source)
{
    // lots of opportunity for copy elision and RVO here.
    std::sort(std::begin(source), std::end(source));
    return source;
}

解决这个问题的具体问题:

void foo(const char* const text);

答案是合格的," NO"这是因为:

  1. 第二个const不向任何人提供任何保证。被调用的函数可以简单地复制指针text并修改副本。

  2. 它使用另一个词来混淆API,而不添加任何值。

  3. 但是有一个反驳论点,第二个const不是为了调用者的利益,而是为了foo()的实现者。

    在这种情况下,它为他提供了一个安全的const指针,指向const数据,他可以使用它而不会意外地改变。

    反计数器的论点是,所有这一切都是通过接口泄漏实现细节。

答案 2 :(得分:0)

const让您一眼就能看到以下代码中未修改变量。因此,它有助于更​​快地或完全理解代码。因此,一般的建议是在代码中慷慨地使用const,无论它在何处都可以使用。

C ++ 11移动语义与该建议冲突。例如,如果函数采用string参数并且只将值存储在某处,则形式参数应该更好 not const,以便它可以有效move const 1}}来自。在我看来,这里有一个缺少语言的功能,一种方式可以说 在此之后,变量不能也不会被使用 ,所以编译器知道,因此它可以在代码范围内逻辑const,它可以带来有用的值。

也就是说,C ++并不完全支持它通过constconstexpr关键字提供的有限类型const。这是一种耻辱。但即使在所有需要它的情况下都不能轻易使用#include <Arduino_FreeRTOS.h> #include <croutine.h> #include <event_groups.h> #include <FreeRTOSConfig.h> #include <FreeRTOSVariant.h> #include <list.h> #include <mpu_wrappers.h> #include <portable.h> #include <portmacro.h> #include <projdefs.h> #include <queue.h> #include <semphr.h> #include <StackMacros.h> #include <task.h> #include <timers.h> (因为它阻止了移动优化),优秀的程序员当然会在它与之不冲突的任何地方使用它。其他问题,因为几乎所有对代码可能影响的约束,都有助于理解和维护代码。