说我有以下功能:
const std::string& Cat::getKittenName() const
{
Kitten* kitty = getKitty();
return kitty->getName();
}
Run Code Online (Sandbox Code Playgroud)
哪里Kitten::getName返回一个const std::string&如何最好地处理的情况kitty是nullptr哪个?我可以返回,std::string("")但后来我返回一个临时和实际保证未定义行为的引用.我可以更改getKittenName函数返回一个std::string来解决这个问题,但后来我为所有kitty可用的情况引入了一个冗余副本.现在我觉得最好的选择是:
const std::string& Cat::getKittenName() const
{
Kitten* kitty = getKitty();
if (kitty)
{
return kitty->getName();
}
static std::string empty("");
return empty;
}
Run Code Online (Sandbox Code Playgroud)
唯一的问题可能是"魔法静力学"不可用.这个解决方案有什么问题,或者有更好的方法吗?
Rei*_*ica 25
你有几个选择,真的.
最简单的就是返回std::string,但是你提到你出于性能原因不希望这样做.我会说你应首先进行分析,以确保它会出现明显的性能问题,因为所有其他解决方案都会使代码更复杂,因此至少有一点难以维护.但是,让我们说它看起来确实很重要.
如果您担心未实现线程安全的函数范围静态,则可以将回退值创建为以下静态成员Cat:
class Cat {
static const std::string missingKittenName;
public:
const std::string& Cat::getKittenName() const
{
Kitten* kitty = getKitty();
if (kitty)
return kitty->getName();
else
return missingKittenName;
}
};
Run Code Online (Sandbox Code Playgroud)由于Kitten::getName()显然返回引用(否则你不会担心副本),你也可以返回一个指针:
const std::string* Cat::getKittenName() const
{
Kitten* kitty = getKitty();
if (kitty)
return &kitty->getName();
else
return nullptr;
}
Run Code Online (Sandbox Code Playgroud)您可以返回对字符串的可选引用:
boost::optional<const std::string&> Cat::getKittenName() const
{
Kitten* kitty = getKitty();
if (kitty)
return kitty->getName();
else
return boost::none;
}
Run Code Online (Sandbox Code Playgroud)
由于C++ 17 optional是标准库的一部分std::optional,因此不再需要依赖Boost.
如果缺少名称这一事实是异常情况(错误),您可以抛出异常:
const std::string& Cat::getKittenName() const
{
Kitten* kitty = getKitty();
if (kitty)
return kitty->getName();
else
throw std::invalid_argument("Missing kitten");
}
Run Code Online (Sandbox Code Playgroud)返回对const static std :: string的引用.
原因:
如果你在pre-c ++ 11编译器上有多线程,那么你需要编写一个线程安全的单例来制作默认字符串,或者在文件范围内定义它.
C++ 11:
const std::string& Cat::getKittenName() const
{
static const std::string noname { /* empty string */ };
Kitten* kitty = getKitty();
if (kitty)
{
return kitty->getName();
}
return noname;
}
Run Code Online (Sandbox Code Playgroud)
C++ 03:
namespace {
const std::string noname;
}
const std::string& Cat::getKittenName() const
{
Kitten* kitty = getKitty();
if (kitty)
{
return kitty->getName();
}
return noname;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3881 次 |
| 最近记录: |