使用“const”关键字进行 C 类型转换

新手上路,请多包涵

我通常在 C/C++ 代码中使用 C 类型转换。我的问题是,在转换类型中添加“const”关键字对结果有什么意义吗?

例如,我可以想出几个场景:

 const my_struct *func1()
{
   my_struct *my_ptr = new my_struct;

   // modify member variables

   return (const my_struct *)my_ptr;
   // return my_instance;
}

在这一个中,该函数构造了一个结构的新实例,并将其转换为一个常量指针,因此调用者将无法进一步修改其内部状态,除非将其删除。是否需要、推荐或根本不需要“const”强制转换,因为任一 return 语句都有效。

在这一个中, my_basemy_derive 的基类。

 const my_base *func2(const my_derive *my_ptr)
{
    return (const my_base *)my_ptr;
    // return (my_base *)my_ptr;
}

由于 my_ptr 已经是一个 const 指针,使用 (my_base *) 进行强制转换会涉及用于删除 const 的 const_cast 和返回时另一个隐式 const_cast 吗?

是否有任何理由将“const”添加到整数函数参数,因为更改它永远不会影响函数外部的状态?

 void func3(const int i)
{
    // i = 0; is not allowed, but why, as it is harmless?
}

在转换整数时添加“const”怎么样?我认为这应该类似于 func2()

 void func4(short i)
{
    const unsigned int j = (const unsigned int) i;
    // const unsigned int j = (unsigned int) i;
}

如我错了请纠正我。考虑到类型转换可能是一个常见问题解答,我不确定这是否与其他任何内容重复。谢谢!

原文由 Crend King 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 368
2 个回答

在转换类型中添加 const 关键字意味着结果将是恒定的。以下将不会在 C++ 中编译(在 C 中无效):

 int* x = (const int*)malloc(10); // cannot convert from 'const int *' to 'int *'

你真的不应该在你的 C++ 代码中使用 C 类型转换。它不安全,仅应用于与遗留 C 代码兼容。您应该改用 C++ 强制转换。

func3 通常情况下 const 不使用限定符。如果函数参数没有指针或引用类型,则没有很大的理由将 const 限定符添加到函数参数中。考虑以下:

 void func3(      TYPE i);  // no reason to use `const`
void func3(const TYPE& i); // use `const`, so as not to accidentally change `i`

当您将左值分配给右值时,如 func4 ,无需在强制转换表达式中显式指定 const 限定符。左值到右值的转换将根据 C++ 标准 4.1 隐式执行。

原文由 Kirill V. Lyadvinsky 发布,翻译遵循 CC BY-SA 2.5 许可协议

const 添加到演员表就像将 const 添加到任何其他类型说明符 --- 结果对象是 const 。这意味着什么取决于上下文。 If you add const at the top level (eg const int or const foo or int* const , then you just have a const 对象。在大多数情况下,它可以像非 const 对象一样被复制和分配(尽管有一些例外,如 std::auto_ptr )。

如果您将 const 添加到指针,那么您也可以将其添加到指向的类型。 eg int * const is a const pointer to a plain int , whereas const int* or int const* is a plain pointer to一个 const int

 int i;
int* p = (int* const) &i; // fine; top-level const not a problem
int* p2 = (int const*) &i; // error; pointed-to object is const, so this is preserved
int const* p3= (int const*) &i; // OK

const 在参数声明的顶层就像声明任何其他局部变量一样 const --- 您不能在函数体内修改命名对象。但是,这 const 不构成函数类型的一部分,因此您可以在没有它的情况下前向声明该函数(至少使用符合标准的编译器)。

 void func(int i); // forward-declare func
void func(const int i) // this matches the declaration
{
    // i is const here
}

这可以说是很好的风格 --- 无论变量是否被视为 const 函数内部都是一个实现细节,所以不应该在原型中。在定义中,如果您不打算修改它,它遵循声明某些东西 const 的准则。

在参数声明的其他地方(例如,作为指针的一部分)使用 const 确实会影响函数类型,就像强制转换一样。

原文由 Anthony Williams 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题