繁体   English   中英

c ++ const char * to char *

[英]c++ const char* to char*

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

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或为空。

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

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

不会自动进行数据复制。

你也必须返回一个const char* 在虚掷的行为const ,并试图修改通过该指针原来的字符串是不确定的,如果原始数据最初是const :如字符串文字。

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

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

2011年标准说(5.2.11 / 3):

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

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

它还说(5.2.11 / 7):

[注意:根据对象的类型,通过指针,左值或指向数据成员的指针的写入操作会导致const-qualifier的const_cast产生未定义的行为(7.1.6.1)。 - 尾注]

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

关于您的代码审核问题:

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

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

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

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

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

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

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

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

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分配并按值返回。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM