[英]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 *,所以调用者不能修改它或根本不返回它。
布尔变量可以使您的代码更清晰,避免代码重复。
转换值不会复制它。 如果要复制它,则必须通过值传递,通过指针或引用传递将允许用户操作返回的值(除非它是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.