C++ const char* 到 char*
c++ const char* to char*
我有以下函数,它最初对函数参数执行一些验证。
char *doSomething(const char* first, const char* second) {
if((first == nullptr || *first == '[=10=]') && (second == nullptr || *second == '[=10=]')) {
return nullptr;
} else if (first == nullptr || *first == '[=10=]') {
return (char *) second;
} else if (second == nullptr || *second == '[=10=]') {
return (char *) first;
}
//doSomething
}
是否将函数参数 return 转换为指向内存中不同区域的新 char*
?我不想让有人使用这个函数来操纵常量参数指向的值。如果一个参数为 nullptr
或为空,我希望新的 char*
被 return 编辑为与参数之一相同的值。
跟进:布尔变量会更好吗?我意识到我对每个变量执行了两次相同的检查,但我不会在此函数代码的其他任何地方使用此布尔值。
不,它不会生成任何新对象,它会简单地将 const
丢弃到您声明为不可变的内存区域。 通常会导致可怕的未定义行为,但如果它们来自非const
指针,你会没事的(编辑 - 感谢@anatolyg)。
不会自动复制数据。
你也必须 return 一个 const char*
。如果原始数据最初是 const
,则放弃 const
并尝试通过该指针修改原始字符串的行为是未定义的:例如字符串文字。
如果需要 char*
指针,请在函数外部进行深拷贝。
更好的是,将所有这些合并并通过 const
指针传递 std::string
如果 nullptr
仍然被允许,或者通过 const
引用传递 const
如果它不是。 =18=]
您可能 return 指向第一个或第二个参数的指针,以便函数的调用者可以修改它指向的数据。您在技术上 returning 新指针(它的副本)但是由于指针的性质,调用者可以用它修改数据。
如果它对您不利,您可以 return const char *,这样调用者就不能修改它或根本不修改它。
布尔变量可以让你的代码更清晰,避免代码重复。
转换值不会复制它。如果要复制它,则必须按值传递,按指针或引用传递将允许用户操作返回值(除非它是 const
)。
我不明白你为什么担心用户操纵参数,因为它们实际上是恒定的。
至于空值检查,不需要使用 bool
。空检查使用起来很便宜(性能方面)。
2011 年标准说 (5.2.11/3):
The result of a pointer const_cast refers to the original object.
这很简单,可以回答您最初的问题。
它还说 (5.2.11/7):
[ Note: Depending on the type of the object, a write operation through
the pointer, lvalue or pointer to data member resulting from a
const_cast that casts away a const-qualifier may produce undefined
behavior (7.1.6.1). —end note ]
这意味着有时甚至可以通过新指针写入对象。不正常的示例是指向驻留在 read-only 内存中的对象的指针。这已经让人们使用指向字符串文字的指针,并且在嵌入式系统中经常发生常量。据我所知,演员表本身从来没有未定义的行为。
关于您的代码审查问题:
- 正如其他人所说,无论如何return一个const char。
- 调用者对结果做了什么吗?如果不是,return 表示成功或失败的布尔值,或表示几种失败模式的整数。
- 如果调用者使用returned char指针,你return用什么表示成功?三种可能的错误情况用完了立即可用的 return 值。考虑 returning 错误代码并传递实际的 char 指针结果为 "out parameter"(指向 char 指针的指针)。
我会使用一个布尔标志来避免代码重复并减少重复:
bool secondIsEmpty = second == nullptr || *second == '[=10=]';
if( first == nullptr || *first == '[=10=]' )
return secondIsEmpty ? nullptr : second;
else
if( secondIsEmpty )
return first;
对于 char *
,您应该将 return 类型更改为 const char *
并从您的代码中删除 C 类型转换(无论如何您应该使用 const_cast<>)。如果您确实需要 return 来自该函数的可变字符串,这会使它变得更加复杂。您要么必须接受可变字符串作为参数,要么在某处创建缓冲区。在那种情况下,您可能应该 return 指向字符串的智能指针,由 new
分配,或者更好地使用 std::string
和 return 按值分配。
(这个回答主要是side-question如何让代码更好)
正如这里的人所说,您可能想要 return 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;
}
}
你的代码思路大致是:
Find and return the non-empty string, with preference to second
one; if there is none, return 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
.
进行比较更具可读性
我有以下函数,它最初对函数参数执行一些验证。
char *doSomething(const char* first, const char* second) {
if((first == nullptr || *first == '[=10=]') && (second == nullptr || *second == '[=10=]')) {
return nullptr;
} else if (first == nullptr || *first == '[=10=]') {
return (char *) second;
} else if (second == nullptr || *second == '[=10=]') {
return (char *) first;
}
//doSomething
}
是否将函数参数 return 转换为指向内存中不同区域的新 char*
?我不想让有人使用这个函数来操纵常量参数指向的值。如果一个参数为 nullptr
或为空,我希望新的 char*
被 return 编辑为与参数之一相同的值。
跟进:布尔变量会更好吗?我意识到我对每个变量执行了两次相同的检查,但我不会在此函数代码的其他任何地方使用此布尔值。
不,它不会生成任何新对象,它会简单地将 const
丢弃到您声明为不可变的内存区域。 通常会导致可怕的未定义行为,但如果它们来自非const
指针,你会没事的(编辑 - 感谢@anatolyg)。
不会自动复制数据。
你也必须 return 一个 const char*
。如果原始数据最初是 const
,则放弃 const
并尝试通过该指针修改原始字符串的行为是未定义的:例如字符串文字。
如果需要 char*
指针,请在函数外部进行深拷贝。
更好的是,将所有这些合并并通过 const
指针传递 std::string
如果 nullptr
仍然被允许,或者通过 const
引用传递 const
如果它不是。 =18=]
您可能 return 指向第一个或第二个参数的指针,以便函数的调用者可以修改它指向的数据。您在技术上 returning 新指针(它的副本)但是由于指针的性质,调用者可以用它修改数据。
如果它对您不利,您可以 return const char *,这样调用者就不能修改它或根本不修改它。
布尔变量可以让你的代码更清晰,避免代码重复。
转换值不会复制它。如果要复制它,则必须按值传递,按指针或引用传递将允许用户操作返回值(除非它是 const
)。
我不明白你为什么担心用户操纵参数,因为它们实际上是恒定的。
至于空值检查,不需要使用 bool
。空检查使用起来很便宜(性能方面)。
2011 年标准说 (5.2.11/3):
The result of a pointer const_cast refers to the original object.
这很简单,可以回答您最初的问题。
它还说 (5.2.11/7):
[ Note: Depending on the type of the object, a write operation through the pointer, lvalue or pointer to data member resulting from a const_cast that casts away a const-qualifier may produce undefined behavior (7.1.6.1). —end note ]
这意味着有时甚至可以通过新指针写入对象。不正常的示例是指向驻留在 read-only 内存中的对象的指针。这已经让人们使用指向字符串文字的指针,并且在嵌入式系统中经常发生常量。据我所知,演员表本身从来没有未定义的行为。
关于您的代码审查问题:
- 正如其他人所说,无论如何return一个const char。
- 调用者对结果做了什么吗?如果不是,return 表示成功或失败的布尔值,或表示几种失败模式的整数。
- 如果调用者使用returned char指针,你return用什么表示成功?三种可能的错误情况用完了立即可用的 return 值。考虑 returning 错误代码并传递实际的 char 指针结果为 "out parameter"(指向 char 指针的指针)。
我会使用一个布尔标志来避免代码重复并减少重复:
bool secondIsEmpty = second == nullptr || *second == '[=10=]';
if( first == nullptr || *first == '[=10=]' )
return secondIsEmpty ? nullptr : second;
else
if( secondIsEmpty )
return first;
对于 char *
,您应该将 return 类型更改为 const char *
并从您的代码中删除 C 类型转换(无论如何您应该使用 const_cast<>)。如果您确实需要 return 来自该函数的可变字符串,这会使它变得更加复杂。您要么必须接受可变字符串作为参数,要么在某处创建缓冲区。在那种情况下,您可能应该 return 指向字符串的智能指针,由 new
分配,或者更好地使用 std::string
和 return 按值分配。
(这个回答主要是side-question如何让代码更好)
正如这里的人所说,您可能想要 return 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;
}
}
你的代码思路大致是:
Find and return the non-empty string, with preference to
second
one; if there is none, returnnullptr
.
这样表示可能更容易:
const char *FindNonEmpty(const char* first, const char* second)
{
if (second && *second)
return second;
else if (first && *first)
return first;
else
return nullptr;
}
我在布尔上下文中使用了指针和字节。这是一个品味问题。您可能想使用显式比较;然而,有些人认为将指针用作布尔值比将其与 nullptr
.