c++ const char* to char*

c++ const char* to char*

本文关键字:char to const c++      更新时间:2023-10-16

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

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

强制转换函数参数是否返回指向内存中不同区域的新char*?我不希望有人使用此函数来操作常量参数所指向的值。如果某个参数为nullptr或为空,我希望返回一个新的char*,该值与其中一个参数的值相同。

后续:这里的布尔变量会更好吗?我意识到我对每个变量执行了两次相同的检查,但我不会在这个函数代码的其他地方使用这个布尔值。

不,它不生成任何新对象,只是将const丢弃到您声明为不可变的内存区域。通常会导致可怕的未定义行为,但如果它们来自非const指针,你就可以了(编辑-感谢@analolyg)。

不会自动复制数据。

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

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

更好的是,如果nullptr仍然被允许,则对所有这些进行bin,并通过const指针传递std::string,如果不允许,则通过const引用传递。

2011年标准规定(5.2.11/3):

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

这很简单,回答了你最初的问题。

它还说(5.2.11/7):

[注意:根据对象的类型,通过从强制转换const限定符的const_cast可能会产生未定义的行为(7.1.6.1)。--结束注释]

这意味着有时甚至可以通过新指针写入对象。不好的例子是指向驻留在只读内存中的对象的指针。这让使用指向字符串文字的指针的人很头疼,在嵌入式系统中常量也经常发生这种情况。在我看来,演员阵容本身从未有过不明确的行为。

关于您的代码审查问题:

  • 正如其他人所说,无论如何都要返回一个const字符
  • 调用者对结果做了什么吗?如果不是,则返回一个bool,表示成功或失败,或者返回一个int表示几种失败模式
  • 如果调用者使用返回的char指针,那么返回什么来表示成功?这三种可能的错误情况会用完立即可用的返回值。考虑返回一个错误代码,并在"out参数"(指向字符指针的指针)中传递实际的字符指针结果

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

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

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

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

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

至于空检查,使用bool是不必要的。空检查的使用成本很低(性能方面)。

我会使用一个布尔标志来避免代码重复,并使其不那么容易:

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

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

(这个答案主要是关于如何使代码变得更好的一个附带问题)

正如这里的人所指出的,您可能想要返回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进行比较更具可读性。