C++ 返回带有错误检查的“const std::string&”的方法
我正在编写一个函数,我想返回const std::string&。让我们看看代码C++ 返回带有错误检查的“const std::string&”的方法,c++,C++,我正在编写一个函数,我想返回const std::string&。让我们看看代码 class A { public: const std::string& GetString() const { if (list.empty()) { return "Warning!"; // how to get around this line. } return list[0];
class A
{
public:
const std::string& GetString() const
{
if (list.empty())
{
return "Warning!"; // how to get around this line.
}
return list[0];
};
protected:
std::vector<std::string> list;
};
以上代码就是一个例子。基本思想是编写一个返回常量引用的函数,但也能够检查错误
那么,如何避开返回警告
谢谢,
如果你真的想避免使用例外,那是我的第一选择,你可以考虑这个:class A
{
public:
const std::string& GetString() const
{
if (list.empty())
{
return warning;
}
return list[0];
};
protected:
std::vector<std::string> list;
private:
static std::string warning;
};
// in *.cpp
std::string A::warning = "warning";
如果你真的想避免使用例外,这是我的第一选择,你可以考虑这个:
class A
{
public:
const std::string& GetString() const
{
if (list.empty())
{
return warning;
}
return list[0];
};
protected:
std::vector<std::string> list;
private:
static std::string warning;
};
// in *.cpp
std::string A::warning = "warning";
您可以在此函数中引发异常,并添加一个函数来检查列表是否为空。然后调用方可以在调用GetString之前进行检查。但是如果他们没有做到这一点,他们会得到一个不能忽略的异常。您可以在此函数中抛出一个异常,并添加一个函数来检查列表是否为空。然后调用方可以在调用GetString之前进行检查。但如果他们做不到这一点,他们就会得到一个不能忽视的例外
if (list.empty()) {
static std::string w("Warning!");
return w;
}
因为您返回的是常量引用,所以始终返回对同一对象的引用并不重要
因为您返回的是常量引用,所以始终返回对同一对象的引用并不重要。如果您不想使用异常,那么无论采用哪种方法都有利弊,我首先要问,要求调用方首先调用isValid方法是否合理
class A
{
public:
bool IsStringValid() const
{
return !list.empty();
}
const std::string& GetString() const
{
if (list.empty())
{
return "";
}
return list[0];
};
protected:
std::vector<std::string> list;
private:
static QString warning;
};
如果是我,我可能会让它返回一个const std::string*,因此NULL是一个选项,或者像Fiktik建议的那样定义一个sentinel值。如果你不想使用异常,无论哪种方法都有利弊,我首先会问,要求调用方首先调用isValid方法是否合理
class A
{
public:
bool IsStringValid() const
{
return !list.empty();
}
const std::string& GetString() const
{
if (list.empty())
{
return "";
}
return list[0];
};
protected:
std::vector<std::string> list;
private:
static QString warning;
};
如果是我,我可能会让它返回一个const std::string*,因此NULL是一个选项,或者按照Fiktik的建议定义一个sentinel值。如果您对使用字符串引用感兴趣,为什么不将字符串引用作为参数并返回布尔成功/失败标志
class A
{
public:
const bool GetString(std::string& outString) const
{
if (list.empty())
return false;
outString = list[0];
return true;
};
protected:
std::vector<std::string> list;
};
实现了相同的结果,并给出了一个简单的布尔结果
编辑:正如费鲁乔指出的那样,这不是一个可以掉以轻心的方法。以这种方式为输出使用参数容易引起混淆和错误,应谨慎使用,并在使用时做好记录。如果您对使用字符串引用感兴趣,为什么不将字符串引用作为参数并返回布尔成功/失败标志
class A
{
public:
const bool GetString(std::string& outString) const
{
if (list.empty())
return false;
outString = list[0];
return true;
};
protected:
std::vector<std::string> list;
};
实现了相同的结果,并给出了一个简单的布尔结果
编辑:正如费鲁乔指出的那样,这不是一个可以掉以轻心的方法。以这种方式使用参数进行输出容易造成混乱和错误,应谨慎使用,并在使用的地方做好记录。很高兴知道这一点。那么问题是什么?你可以抛出一个异常。也许我可以直接返回std::string,但还有其他想法吗?@Snowfish在正常情况下,按值返回std::string并不太昂贵-它使用隐式共享,因此真正复制的是一个轻量级包装器,而不是数据本身。所以,是的,这也是一个很好的可能性。如果您按值返回,那么现在大多数编译器都会执行一种称为返回值优化的操作。他们不会构造一个临时对象只是为了将其复制到最终位置,他们会直接构造结果,如果它应该运行的话-希望这是可以理解的。很高兴知道这一点。那么问题是什么?你可以抛出一个异常。也许我可以直接返回std::string,但还有其他想法吗?@Snowfish在正常情况下,按值返回std::string并不太昂贵-它使用隐式共享,因此真正复制的是一个轻量级包装器,而不是数据本身。所以,是的,这也是一个很好的可能性。如果您按值返回,那么现在大多数编译器都会执行一种称为返回值优化的操作。他们不会构建一个临时对象只是为了将其复制到最终位置,他们会直接构建结果——希望这是可以理解的。+1也比我的好。除了我仍然更喜欢使用错误标志,因为它们测试速度更快。我更喜欢在这种情况下使用空字符串,因为它更干净,测试速度更快,但我一直在尝试保持原始行为。另外,我不知道一个空字符串是否已经是有效的返回值。+1也比我的好。除了我仍然更喜欢使用错误标志,因为它们测试速度更快。我更喜欢在这种情况下使用空字符串,因为它更干净,测试速度更快,但我一直在尝试保持原始行为。另外,我不知道一个空字符串是否已经是一个有效的返回值。所以,通常的问题是:谁拥有一个std::string*,谁将删除它?如果你返回一个const std::string*,你几乎是在声明所有权,或者至少告诉调用方他们不负责。编译器不允许您删除cons
t指针。为什么投票被否决?那么,通常的问题是:谁拥有一个std::string*,谁将删除它?如果你返回一个const std::string*,你几乎是在声明所有权,或者至少告诉调用方他们不负责。编译器不允许您删除常量指针。为什么投票被否决?这肯定会+1起作用,但一般来说,通过参数列表返回值不是一个好主意。@Ferrucio:同意。我当然会尽量避免这件事,但就像所有这些潜在的不可靠做法一样,如果所有其他方法都不起作用,它也有它的用处。这肯定会起到+1的作用,但一般来说,通过参数列表返回值不是一个好主意。@Ferrucio:同意。我当然会尽可能地避免这件事,但就像所有这些潜在的狡猾的做法一样,如果所有其他途径都不起作用,它也有它的用处。