C++;可以为空的字符串 我习惯于在C++应用程序中传递这样的字符串: void foo(const std::string& input) { std::cout << input.size() << std::endl; } void bar() { foo("stackoverflow"); }
我可以将C++;可以为空的字符串 我习惯于在C++应用程序中传递这样的字符串: void foo(const std::string& input) { std::cout << input.size() << std::endl; } void bar() { foo("stackoverflow"); },c++,string,null,C++,String,Null,我可以将foo更改为: void foo(const std::string* input) { // TODO: support NULL input std::cout << input->size() << std::endl; } 我开始考虑从std::string继承并添加null属性,但我不太确定这是个好主意。对于可以为NULL的参数,最好只使用const char*字符串,但是如果我想保存字符串(或NULL)的副本而不必自己管理其内存,该怎么
foo
更改为:
void foo(const std::string* input)
{
// TODO: support NULL input
std::cout << input->size() << std::endl;
}
我开始考虑从std::string
继承并添加null
属性,但我不太确定这是个好主意。对于可以为NULL的参数,最好只使用const char*
字符串,但是如果我想保存字符串(或NULL)的副本而不必自己管理其内存,该怎么办?(见等)
有什么聪明的解决方案吗?如果您只使用:
void foo(const char *xinput)
{
if (xinput == NULL) {
// do something exceptional with this
return;
}
std::string input(xinput);
// remainder of code as usual
}
是的,这确实会导致额外的分配和复制,调用该函数会更为冗长,因为在通常情况下需要使用
.c_str()
,但它确实提供了所需的语义。我个人会将语义更改为传递空std::strings,而不是NULL:
void foo(const std::string& input)
{
if (!input.empty())
std::cout << input.size() << std::endl;
}
void bar()
{
foo("");
}
void foo(const std::string和input)
{
如果(!input.empty())
std::cout如果希望类型为null,则将其设置为指针。传递字符串指针而不是引用,因为这正是指针可以做的,而引用不能。引用始终指向同一个有效对象。指针可以设置为null,也可以重置为指向另一个对象。因此,如果需要指针c要做的就是使用指针
或者,使用boost::optional,它允许使用更安全的方式指定“此变量可能包含值,也可能不包含值”
当然,也可以更改语义,这样您可以使用空字符串而不是null,传递一个单独的bool参数来指定字符串是否可用,或者重构,这样您就不需要这个了。为什么不重载函数,并且不给第二个重载参数?然后两个重载都可以在内部调用一个函数,它提供读取逻辑,并向其自身传递一个指向std::string
的指针
void foo_impl(string const* pstr) { … }
void foo(string const& str) {
foo_impl(&str);
}
void foo() {
foo_impl(0);
}
函数重载来拯救
void foo( const std::string& input )
{
std::cout << input << std::endl;
// do more things ...
}
void foo( const char* input )
{
if ( input != NULL ) foo( std::string(input) );
}
void foo(const std::string和input)
{
std::cout或者,混合前面的两个答案:
void fooImpl( const char* input )
{
if ( input != NULL )
std::cout << input << std::endl;
}
void foo( const std::string& input )
{
fooImpl(input.c_str());
}
void foo( const char* input )
{
fooImpl(input);
}
void fooImpl(常量字符*输入)
{
如果(输入!=NULL)
Std::CUT< P>绝对不继承从代码> STD::String 。继承是C++中最紧密的耦合,而只寻找可空性,可以简单地使用<代码> const char */COD>,重载,或者简单地<代码> STD::Stry*<代码>如果您真的想要。为什么要NULL?IS?足够了?@Tim:也许吧。这样我就不用老是检查那些参数是否为NULL,我会用empty()检查“无值”。重新引入NULL是假的。如果你需要可怕的NULL指针,为什么首先要使用引用?实际上,使用引用最重要的原因之一是你可以确保它不是NULL。我不会这么做,这可能会误导。这是重点,真的;这是一个抽象。使用应该很简单,除非你非常关心性能。@sudarkoff:我不同意。问题本身具有误导性,需要抽象。解决方案非常优雅。至于性能问题,“过早优化,等等。”…+1.两点:首先,空字符串可以是有效值,与null分开。其次,当您只关心大小是否为非零时,使用empty()
而不是size()
被认为是更好的解决方案。boost::optional
或指针。改为使用empty()。对原始问题的评论指出,使用NULL表示“不知道值”,使用empty表示“空值”。这使得这个答案是错误的。但我想再看一看,因为传递指针会带来“谁拥有这个指针?”问题。在这种情况下,boost::optional或智能指针将是最佳选择。
void foo( const std::string& input )
{
std::cout << input << std::endl;
// do more things ...
}
void foo( const char* input )
{
if ( input != NULL ) foo( std::string(input) );
}
void fooImpl( const char* input )
{
if ( input != NULL )
std::cout << input << std::endl;
}
void foo( const std::string& input )
{
fooImpl(input.c_str());
}
void foo( const char* input )
{
fooImpl(input);
}