c ++ const char * to char *

时间:2015-12-30 19:47:51

标签: c++ pointers casting constants nullptr

我有以下函数,它最初对函数参数执行一些验证。

char *doSomething(const char* first, const char* second) {

    if((first == nullptr || *first == '\0') && (second == nullptr || *second == '\0')) {
        return nullptr;
    } else if (first == nullptr || *first == '\0') {
        return (char *) second;
    } else if (second == nullptr || *second == '\0') {
        return (char *) first;
    }
    //doSomething
}

强制转换函数参数会返回指向内存中不同区域的新char*吗?我不想允许使用此函数的人操纵常量参数指向的值。我希望返回一个新的char*,其值与其中一个参数相同(如果一个是nullptr或为空。

跟进:布尔变量会更好吗?我意识到我正在对每个变量执行两次相同的检查,但我不会在此函数的代码中的任何其他位置使用此布尔值。

7 个答案:

答案 0 :(得分:5)

不,它不会使任何新对象简单地将const强制转换为您声明为不可变的内存区域。哪个通常会导致可怕的未定义行为,但如果它们来自非const指针,那么你就可以了(编辑 - 感谢@anatolyg)。

答案 1 :(得分:2)

不会自动复制数据。

您也必须返回const char*。如果原始数据最初为const,则抛弃const并尝试通过该指针修改原始字符串的行为是未定义的:例如字符串文字。

如果需要char*指针,请在函数外部进行深层复制。

更好的是,如果仍然允许std::string,则通过const指针移除nullptr,如果不是const引用则传递wdio

答案 2 :(得分:2)

2011年标准(5.2.11 / 3):

  

指针const_cast的结果是指原始对象。

这非常简单,可以回答你原来的问题。

它还说(5.2.11 / 7):

  

[注意:根据对象的类型,通过写操作   由a产生的数据成员的指针,左值或指针   抛弃const限定符的const_cast可能会产生undefined   行为(7.1.6.1)。 - 后注]

这意味着有时甚至可以通过新指针写入对象。不合适的示例是指向驻留在只读存储器中的对象的指针。这会使人们使用指向字符串文字的指针,并经常在嵌入式系统中使用常量。就我所见,演员本身并不是未定义的行为。

关于您的代码审核问题:

  • 正如其他人所说,无论如何都要返回一个const char。
  • 来电者是否对结果做了什么?如果没有,则返回指示成功或失败的bool,或返回多种失败模式的int。
  • 如果调用者使用返回的char指针,您返回什么表示成功?三种可能的错误情况会使用立即可用的返回值。考虑返回错误代码并将实际的char指针结果传递给“out参数”(指向char指针的指针)。

答案 3 :(得分:0)

您可能返回指向第一个或第二个参数的指针,因此函数的调用者可以修改它指向的数据。您在技术上返回新指针(它的副本),但由于指针性质,调用者可以使用它修改数据。

如果它不好你可以返回const char *,所以调用者不能修改它或根本不返回它。

布尔变量可以使您的代码更清晰,避免代码重复。

答案 4 :(得分:0)

转换值不会复制它。如果你想复制它,你必须通过值传递,通过指针或引用传递将允许用户操纵返回的值(除非它const)。

我不明白为什么你担心用户操纵参数,因为它们实际上是不变的。

至于空检查,使用bool是不必要的。空检查使用起来很便宜(性能明智)。

答案 5 :(得分:0)

我会使用一个布尔标志来避免代码重复并使其不易发生:

bool secondIsEmpty = second == nullptr || *second == '\0';
if( first == nullptr || *first == '\0' )
    return secondIsEmpty ? nullptr : second;
else
    if( secondIsEmpty )
        return first;

对于char *,您应该将返回类型更改为const char *并从代码中删除C cast(无论如何都应使用const_cast<>)。如果你确实需要从该函数返回可变字符串,使其更复杂。您必须接受可变字符串作为参数,或者在某处创建缓冲区。在这种情况下,您可能应该将智能指针返回到由new分配的字符串,或者更好地使用std::string并按值返回。

答案 6 :(得分:0)

(这个答案主要是关于如何使代码更好的一个侧面问题)

正如此处的人所说,您可能想要返回const char*

const char *doSomething(const char* first, const char* second)
{
    ...
}

这可以让你摆脱演员:

const char *doSomething(const char* first, const char* second)
{
    if (...)
    {
        return nullptr;
    }
    else if (...)
    {
        return second;
    }
    else if (...)
    {
        return first;
    }
}

您的代码的想法大致是:

  

查找并返回非空字符串,优先选择second一个;如果没有,请返回nullptr

可能更容易表示如下:

const char *FindNonEmpty(const char* first, const char* second)
{
    if (second && *second)
        return second;
    else if (first && *first)
        return first;
    else
        return nullptr;
}

我在布尔上下文中使用了指针和字节。这是一个品味问题;你可能想要使用显式比较;但是,有些人认为使用指针作为布尔值比将其与nullptr进行比较更具可读性。