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

时间:2010-08-06 06:42:52

标签: c++ c casting const

我通常在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;
}

在这一个中,该函数构造一个struct的新实例,并将其转换为常量指针,因此除了删除它之外,调用者将无法进一步修改其内部状态。是“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;
}

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

3 个答案:

答案 0 :(得分:6)

在投射类型中添加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`

当你将左值赋给rvalue时,就像在func4中一样,没有必要在强制转换表达式中明确指定const限定符。 Lvalue-to-rvalue转换将根据C ++标准4.1隐式执行。

答案 1 :(得分:5)

向演员表添加const就像将const添加到任何其他类型说明符一样 - 结果对象为const。这意味着什么取决于上下文。如果您在顶层添加const(例如const intconst fooint* const,那么您只有一个const对象。在大多数情况下,这可能是复制和分配就像非const对象一样(虽然有一些例外,如std::auto_ptr)。

如果将const添加到指针,则还可以将其添加到指向类型。例如int * const是指向普通const的{​​{1}}指针,而intconst int*是指向int const*的普通指针。

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(例如作为指针的一部分)会影响函数类型,就像强制转换一样。

答案 2 :(得分:1)

在第一个示例中,在需要const的函数中返回非const将再次捕获它意味着const很重要,但是您无法注意到它,因为如果它不存在则会添加它。
在第二个例子中,它将是一个保持常数的演员 在第三个例子中它是不允许的,因为它是无害的:我将改变其余的功能并且不可恢复。
请记住,将类型放入容器而不是它的类型会将其自动转换为与int放置在长字段中不会保持为int。
你还必须记住,const意味着与汇编程序的私有或公共相同,这没什么。无论你在哪里放置const,生成的汇编代码都不会有任何不同,并且会以相同的速度运行。